winapp-signing

作者: microsoft

為Windows應用程式和MSIX套件建立及管理程式碼簽署憑證。適用於產生憑證、簽署Windows應用程式或安裝程式,或…

npx skills add https://github.com/microsoft/winappcli --skill winapp-signing

When to use

Use this skill when:

  • Generating a development certificate for local MSIX signing and testing
  • Installing (trusting) a certificate on a machine so MSIX packages can be installed
  • Signing an MSIX package or executable for distribution
  • Signing with Azure Trusted Signing (cloud-managed signing identity) via winapp az-sign

Prerequisites

  • winapp CLI installed
  • Administrator access required for cert install (trusting certificates on the machine)

Key concepts

Publisher matching: The publisher in your certificate must exactly match the Publisher attribute in Package.appxmanifest. Most X.500 distinguished names are supported (e.g., CN=MyCompany or OU=Team, O=Corp, C=US), but components must be single-valued and comma-separated — multi-valued RDNs (CN=Foo+OU=Bar) and backslashes aren't supported because the MSIX manifest publisher cannot represent them. Use --manifest when generating to auto-match.

Dev vs. production certs: winapp cert generate creates self-signed certificates for local testing only. For production distribution (Microsoft Store or enterprise), obtain a certificate from a trusted Certificate Authority.

Default password: Generated certificates use password as the default PFX password. Override with --password. That default is publicly known, so a certificate left with it can be used by anyone who obtains the .pfx — keep it to builds that stay on your own machines. With --json, check defaultPasswordIsPublic (always present) and the warnings array before handing the certificate to anything else.

Usage

Generate a development certificate

# Auto-infer publisher from Package.appxmanifest in the current directory
winapp cert generate

# Explicitly point to a manifest
winapp cert generate --manifest ./path/to/Package.appxmanifest

# Set publisher manually (when no manifest exists yet)
winapp cert generate --publisher "CN=Contoso, O=Contoso Ltd, C=US"

# Custom output path and password
winapp cert generate --output ./certs/myapp.pfx --password MySecurePassword

# Custom validity period
winapp cert generate --valid-days 730

# Overwrite existing certificate
winapp cert generate --if-exists overwrite

Output: devcert.pfx (or custom path via --output).

Install (trust) a certificate

# Trust the certificate on this machine (requires admin/elevated terminal)
winapp cert install ./devcert.pfx

# Force reinstall even if already trusted
winapp cert install ./devcert.pfx --force

This adds the certificate to the local machine's Trusted Root Certification Authorities store. Required before double-clicking MSIX packages or running Add-AppxPackage.

Sign a file

# Sign an MSIX package
winapp sign ./myapp.msix ./devcert.pfx

# Sign with custom password
winapp sign ./myapp.msix ./devcert.pfx --password MySecurePassword

# Sign with timestamp for production (signature remains valid after cert expires)
winapp sign ./myapp.msix ./production.pfx --timestamp http://timestamp.digicert.com

Bundle signing

When packaging multiple architectures into an .msixbundle, only the bundle needs to be signed — the signature covers all packages inside. The individual .msix slices do not need separate signatures.

Note: The package command can sign automatically when you pass --cert, so you often don't need sign separately.

Sign with Azure Trusted Signing (cloud signing)

For production-grade signing without managing a PFX file, use winapp az-sign to sign with Azure Trusted Signing. The signing identity (certificate) is managed in Azure, so no private key ever lives on the machine.

# Interactive: discover subscription, account, and profile (prompts for any not provided)
winapp az-sign ./app.msix

# Fully specified — no prompting (ideal for CI/CD)
winapp az-sign ./app.msix --subscription <sub-id> --resource-group <rg> --account <account> --profile <profile>

# Reuse an existing metadata.json (skips resource discovery and identity selection; authentication may still be interactive)
winapp az-sign ./app.msix --metadata-file ./metadata.json

Authentication: az-sign uses Azure's standard credential chain (DefaultAzureCredential). In CI/CD, set AZURE_TENANT_ID, AZURE_CLIENT_ID, and AZURE_CLIENT_SECRET (or GitHub Actions OIDC / managed identity). An existing Azure CLI session (az login, including the azure/login GitHub Action) is also honored in any environment. Only when no credentials are found and the session is interactive will az-sign launch az login for you.

Prerequisites: An Azure Code Signing account and certificate profile (created in the Azure portal after identity validation), plus a role assignment granting your identity the Code Signing Certificate Profile Signer role. Signing also requires two machine-wide x64 runtimes that winapp does not install for you (it downloads the raw NuGet signing package, not the official client-tools installer): the x64 .NET 8+ runtime (the signing library is a managed assembly loaded by signtool.exe; winapp's self-contained runtime does not satisfy it) and the x64 Visual C++ Redistributable (https://aka.ms/vs/17/release/vc_redist.x64.exe). Also requires SignTool 10.0.22621.755 or later. If signing fails while loading the dlib (e.g. 0xc000007b or a missing-DLL error) rather than during authentication, install the missing runtime — most often the VC++ Redistributable.

Least-privilege CI: Auto-discovery (listing subscriptions, resource groups, accounts, and profiles) needs read access at a parent scope. To avoid every collection-listing call, pass all four of --subscription, --resource-group, --account, and --profile: az-sign then validates the account and profile with direct resource reads (a GET on each named resource) instead of enumerating the parent collection, so a principal scoped to just that account and profile is sufficient. Omitting any one of them re-introduces a listing call — for example, leaving out --subscription makes az-sign list the subscriptions your identity can access — which a narrowly-scoped principal may not be permitted to do. A principal scoped only to a single certificate profile can skip validation entirely by passing a pre-generated --metadata-file (which specifies the account endpoint and profile directly).

Recommended workflow

  1. Generate cert — winapp cert generate (auto-infers publisher from manifest)
  2. Trust cert (one-time) — winapp cert install ./devcert.pfx (run as admin)
  3. Package + sign — winapp package ./dist --cert ./devcert.pfx
  4. Distribute — share the .msix; recipients must also trust the cert, or use a trusted CA cert

Tips

  • Always use --manifest (or have Package.appxmanifest in the working directory) when generating certs to ensure the publisher matches automatically
  • For CI/CD, store the PFX as a secret and pass the password via --password rather than using the default
  • winapp cert install modifies the machine certificate store — it persists across reboots and user sessions
  • Use --timestamp when signing production builds so the signature survives certificate expiration
  • You can also use the shorthand: winapp package ./dist --generate-cert --install-cert to do everything in one command

Related skills

  • Need to create a manifest first? See winapp-manifest to generate Package.appxmanifest with correct publisher info
  • Ready to package? See winapp-package to create and sign an MSIX in one step
  • Having issues? See winapp-troubleshoot for common error solutions

Troubleshooting

ErrorCauseSolution
"Publisher mismatch"Cert publisher ≠ manifest publisherwinapp cert generate --manifest ./Package.appxmanifest to re-generate with correct publisher
"Access denied" / "elevation required"cert install needs adminRun your terminal as Administrator
"Certificate not trusted"Cert not installed on machinewinapp cert install ./devcert.pfx (admin)
"Certificate file already exists"devcert.pfx already presentUse --if-exists overwrite or --if-exists skip
Signature invalid after time passesNo timestamp used during signingRe-sign with --timestamp http://timestamp.digicert.com
az-sign fails with "No credentials found"No Azure auth in environmentRun az login, or set AZURE_TENANT_ID/AZURE_CLIENT_ID/AZURE_CLIENT_SECRET for CI/CD
az-sign "No Trusted Signing accounts found"No account in the subscription/resource groupCreate a Trusted Signing account and certificate profile in the Azure portal

CLI reference

Run winapp <command> --help for current command options, or winapp --cli-schema for the complete machine-readable command schema.

來自 microsoft 的更多技能

oss-growth
microsoft
開源增長駭客角色
agent-framework-azure-ai-py
microsoft
使用Microsoft Agent Framework Python SDK(agent-framework-azure-ai)构建Azure AI Foundry代理。适用于使用AzureAIAgentsProvider创建持久化代理、使用托管工具(代码解释器、文件搜索、网络搜索)、集成MCP服务器、管理对话线程或实现流式响应。涵盖函数工具、结构化输出和多工具代理。
development
airunway-aks-setup
microsoft
在AKS上設定AI Runway——從裸叢集到執行模型。涵蓋叢集驗證、控制器安裝、GPU評估、供應商設定及首次部署。時機:「設定AI Runway」、「上線AKS叢集」、「安裝AI Runway」、「airunway設定」、「部署模型至AKS」、「在AKS上進行GPU推論」、「在AKS上設定KAITO」、「在AKS上執行LLM」、「在AKS上使用vLLM」、「在AKS上設定模型服務」、「AI Runway控制器」。
devops
appinsights-instrumentation
microsoft
使用Azure Application Insights檢測Web應用程式的指南。提供遙測模式、SDK設定與組態參考。適用時機:如何檢測應用程式、App Insights SDK、遙測模式、什麼是App Insights、Application Insights指南、檢測範例、APM最佳實踐。
devops
applicationinsights-web-ts
microsoft
使用Application Insights JavaScript SDK(@microsoft/applicationinsights-web)為瀏覽器/Web應用程式進行檢測。適用於真實使用者監控(RUM)——頁面檢視、點擊、AJAX/fetch依賴、例外、自訂事件,以及與後端OpenTelemetry追蹤關聯的瀏覽器端GenAI代理追蹤。涵蓋SDK載入器指令碼與npm設定、框架擴充(React、React Native、Angular)、點擊分析、遙測初始化器,以及從瀏覽器發出的代理/工具/模型span的OTel GenAI語意慣例。
devops
azure-ai-anomalydetector-java
microsoft
使用適用於 Java 的 Azure AI 異常偵測器 SDK 建置異常偵測應用程式。在實作單變量/多變量異常偵測、時間序列分析或 AI 驅動監控時使用。
development
azure-ai-language-conversations-py
microsoft
使用 azure-ai-language-conversations Python SDK 實作對話語言理解(CLU)。當使用 ConversationAnalysisClient 分析對話意圖與實體、建置 NLP 功能,或將語言理解整合至應用程式時使用。
development
azure-ai-ml-py
microsoft
Azure Machine Learning SDK v2 for Python。用於機器學習工作區、作業、模型、資料集、計算資源與管線。 觸發詞:「azure-ai-ml」、「MLClient」、「workspace」、「model registry」、「training jobs」、「datasets」。
development