SSL certificate maximum validity is being reduced to 200 days from March 2026. Read more →

Azure Key Vault Code Signing: setup guide

This guide walks you through setting up Azure Key Vault Premium for Code Signing, from creating the vault to signing your first file with AzureSignTool. Works with both OV and EV Code Signing certificates from DigiCert and GlobalSign.

Prerequisites

  • Azure subscription (any tier, including free)
  • .NET 8 SDK or later (for AzureSignTool). Download from dotnet.microsoft.com ↗
  • A Code Signing certificate from FairSSL (DigiCert or GlobalSign, OV or EV). See products below

Only DigiCert and GlobalSign certificates work with Azure Key Vault. Sectigo/Comodo certificates are not compatible because Azure Key Vault does not support their key attestation format.

Step 1: Create an Azure Key Vault (Premium)

Go to the Azure portal and create a new Key Vault resource. The critical setting is the pricing tier.

Key Vault settings

  • Pricing tier: Premium (required for HSM-backed keys. Standard cannot create RSA-HSM keys)
  • Region: Choose a region close to your signing infrastructure
  • Permission model: Azure role-based access control (RBAC) (recommended)
  • Soft-delete: Enabled (default, cannot be disabled)
  • Purge protection: Recommended to enable (prevents accidental permanent deletion)

Azure CLI alternative

az keyvault create \
  --name your-codesign-vault \
  --resource-group your-resource-group \
  --location westeurope \
  --sku premium \
  --enable-purge-protection true

Step 2: Configure RBAC permissions

Azure Key Vault uses a separate permission model for data plane operations. Having Owner or Contributor on the subscription does not automatically give you access to keys and certificates inside the vault.

Required roles for your user account (setup)

  • Key Vault Administrator on the Key Vault resource

Assign via: Key Vault resource → Access control (IAM) → Add role assignment → Key Vault Administrator → select your user.

Required roles for AzureSignTool (signing)

The service principal or managed identity used by AzureSignTool needs these three roles:

  • Key Vault Crypto User (perform signing operations)
  • Key Vault Certificate User (read certificate metadata)
  • Key Vault Secrets User (read certificate chain)

Azure CLI

# Assign Key Vault Administrator to yourself
az role assignment create \
  --role "Key Vault Administrator" \
  --assignee your-email@example.com \
  --scope /subscriptions/{sub-id}/resourceGroups/{rg}/providers/Microsoft.KeyVault/vaults/{vault-name}

Step 3: Generate key and CSR

In the Azure portal, navigate to your Key Vault → Certificates → Generate/Import.

Certificate creation settings

  • Method: Generate
  • Certificate Name: e.g. codesign-2026 (your internal reference)
  • Type of CA: Certificate issued by a non-integrated CA
  • Subject: CN=Your Company Name (must match the name registered with the CA)

Advanced Policy Configuration

  • Extended Key Usages (EKUs): 1.3.6.1.5.5.7.3.3 (Code Signing)
  • Key Type: RSA-HSM
  • Key Size: 4096
  • Content Type: PEM
  • Exportable Private Key: No
  • Enable Certificate Transparency: No (not required for Code Signing)

Click Create. The certificate will appear in the list with status "In progress". Click on it, then click Certificate OperationDownload CSR to get the CSR file.

The private key is generated inside the HSM and never leaves it. The CSR contains only the public key. This is what you submit to FairSSL/the CA for signing.

Step 4: Order certificate and submit CSR

  1. 1
    Order a Code Signing certificate from FairSSL. Choose DigiCert or GlobalSign, OV or EV. Select "Azure Key Vault" as the delivery method. See products below.
  2. 2
    Submit the CSR you downloaded from Azure Key Vault. Paste the PEM content when prompted during the order process.
  3. 3
    Complete organisation validation. FairSSL performs the initial OV validation for GlobalSign in Danish, Swedish and English (often completed same day). The CA then performs an independent second check.
  4. 4
    Receive the signed certificate from the CA. You will typically get several files: your Code Signing certificate, an intermediate certificate and a root certificate. Combine them into a single PEM file (see step 5).

Step 5: Import the signed certificate into Key Vault

We recommend combining all certificates into a single PEM file: your Code Signing certificate first, then the intermediate certificate, and finally the root certificate. This order ensures Azure Key Vault can validate the full certificate chain.

Create the combined PEM file

Open a text editor and paste the certificates in this order (or use the command below):

-----BEGIN CERTIFICATE-----
(your Code Signing certificate)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
(intermediate certificate from the CA)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
(root certificate from the CA)
-----END CERTIFICATE-----

Using the command line, you can concatenate the files directly:

cat codesign.pem intermediate.pem root.pem > fullchain.pem

Upload to Key Vault

Go back to your Key Vault → Certificates → click on the pending certificate → Certificate OperationMerge Signed Request.

Upload the combined PEM file (fullchain.pem). Azure Key Vault will merge the certificate chain with the private key that was generated in step 3.

After merging, the certificate status changes to "Completed" and is ready for signing.

Azure CLI alternative

az keyvault certificate pending merge \
  --vault-name your-codesign-vault \
  --name codesign-2026 \
  --file fullchain.pem

Note the certificate name (e.g. codesign-2026). You will need this for AzureSignTool's -kvc parameter.

Step 6: Create a service principal for signing

AzureSignTool authenticates to Key Vault using a service principal (Azure AD app registration) or a managed identity. For CI/CD pipelines on non-Azure infrastructure, use a service principal.

Create the app registration

  1. Go to Azure Active Directory → App registrations → New registration
  2. Name it something descriptive (e.g. "CodeSign-Pipeline")
  3. Note the Application (client) ID and Directory (tenant) ID
  4. Go to Certificates & secrets → New client secret → create a secret and note the value

Assign Key Vault roles to the service principal

Go to your Key Vault → Access control (IAM) → Add role assignment. Assign all three roles to the service principal:

  • Key Vault Crypto User
  • Key Vault Certificate User
  • Key Vault Secrets User

Azure CLI

# Create app registration
az ad app create --display-name "CodeSign-Pipeline"

# Create service principal
az ad sp create --id {app-id}

# Create client secret
az ad app credential reset --id {app-id} --years 2

# Assign roles (repeat for each role)
az role assignment create \
  --role "Key Vault Crypto User" \
  --assignee {service-principal-id} \
  --scope /subscriptions/{sub-id}/resourceGroups/{rg}/providers/Microsoft.KeyVault/vaults/{vault-name}

Store the client secret securely. In CI/CD pipelines, use secret variables or a vault. Never commit secrets to source control.

Step 7: Install AzureSignTool

AzureSignTool ↗ is a free, open-source drop-in replacement for signtool.exe that signs directly from Azure Key Vault.

dotnet tool install --global AzureSignTool

Requires .NET 8 SDK or later. After installation, AzureSignTool is available as a global command.

Alternative: Jsign (cross-platform)

Jsign ↗ is a Java-based signing tool that also supports Azure Key Vault. Jsign runs on Windows, macOS and Linux, and can sign .exe, .msi, .dll, PowerShell, Office macros and Java/Android apps (as a bridge to jarsigner).

jsign --storetype AZUREKEYVAULT \
  --storepass "YOUR_CLIENT_ID|YOUR_CLIENT_SECRET|YOUR_TENANT_ID" \
  --keystore your-codesign-vault \
  --alias codesign-2026 \
  --tsaurl http://timestamp.digicert.com \
  MyApplication.exe

Jsign is a good alternative if you do not have .NET installed, or if you sign from macOS/Linux.

Step 8: Sign your first file

AzureSignTool sign \
  -kvu https://your-codesign-vault.vault.azure.net \
  -kvc codesign-2026 \
  -kvt YOUR_TENANT_ID \
  -kvi YOUR_CLIENT_ID \
  -kvs YOUR_CLIENT_SECRET \
  -fd sha256 \
  -tr http://timestamp.digicert.com \
  -td sha256 \
  "MyApplication.exe"

Parameter reference

  • -kvu Key Vault URL (found on Key Vault overview page)
  • -kvc Certificate name in Key Vault (the name you chose in step 3)
  • -kvt Azure tenant (directory) ID
  • -kvi Application (client) ID of your service principal
  • -kvs Client secret value
  • -fd File digest algorithm (always use sha256)
  • -tr RFC 3161 timestamp server URL
  • -td Timestamp digest algorithm (always use sha256)

Verify the signature

signtool verify /pa /v "MyApplication.exe"

The output should show "Successfully verified" with your company name and a valid timestamp.

CI/CD integration

AzureSignTool runs in any CI/CD pipeline that supports .NET. Store your Key Vault credentials as secret pipeline variables.

Azure DevOps (YAML)

- task: DotNetCoreCLI@2
  displayName: 'Install AzureSignTool'
  inputs:
    command: 'custom'
    custom: 'tool'
    arguments: 'install --global AzureSignTool'

- script: |
    AzureSignTool sign \
      -kvu $(KeyVaultUrl) \
      -kvc $(CertificateName) \
      -kvt $(TenantId) \
      -kvi $(ClientId) \
      -kvs $(ClientSecret) \
      -fd sha256 \
      -tr http://timestamp.digicert.com \
      -td sha256 \
      "$(Build.ArtifactStagingDirectory)\**\*.exe"
  displayName: 'Sign executables'

GitHub Actions

- name: Install AzureSignTool
  run: dotnet tool install --global AzureSignTool

- name: Sign executables
  run: |
    AzureSignTool sign \
      -kvu ${{ secrets.KEY_VAULT_URL }} \
      -kvc ${{ secrets.CERT_NAME }} \
      -kvt ${{ secrets.AZURE_TENANT_ID }} \
      -kvi ${{ secrets.AZURE_CLIENT_ID }} \
      -kvs ${{ secrets.AZURE_CLIENT_SECRET }} \
      -fd sha256 \
      -tr http://timestamp.digicert.com \
      -td sha256 \
      "output/*.exe"

GitLab CI

sign:
  image: mcr.microsoft.com/dotnet/sdk:8.0
  script:
    - dotnet tool install --global AzureSignTool
    - export PATH="$PATH:$HOME/.dotnet/tools"
    - AzureSignTool sign
        -kvu $KEY_VAULT_URL
        -kvc $CERT_NAME
        -kvt $AZURE_TENANT_ID
        -kvi $AZURE_CLIENT_ID
        -kvs $AZURE_CLIENT_SECRET
        -fd sha256
        -tr http://timestamp.digicert.com
        -td sha256
        "output/*.exe"

Managed identity: On Azure-hosted agents, replace -kvt, -kvi and -kvs with -kvm (use managed identity). This eliminates the need for client secrets entirely.

Timestamping

Always include an RFC 3161 timestamp when signing. This ensures your signatures remain valid after the certificate expires. Code Signing certificates have a maximum validity of 459 days, but timestamped signatures are valid indefinitely.

Recommended timestamp servers

  • http://timestamp.digicert.com (recommended, most stable)
  • http://timestamp.globalsign.com/tsa/r6advanced1

Troubleshooting

"Forbidden" or "Access denied" when signing

The service principal is missing Key Vault RBAC roles. Verify that all three roles are assigned: Key Vault Crypto User, Key Vault Certificate User, and Key Vault Secrets User. RBAC role assignments can take up to 10 minutes to propagate.

"SKU does not support HSM-backed keys"

You created a Standard tier Key Vault. You need Premium. Create a new Key Vault with Premium SKU, or upgrade the existing vault (only possible via CLI).

"Certificate operation is not complete"

You have not yet merged the signed certificate from the CA. Go to Key Vault → Certificates → click the pending certificate → Certificate Operation → Merge Signed Request.

Timestamp fails

Try the alternative timestamp server. Also verify that the signing machine has internet access and can reach the timestamp URL on port 80. Some firewalls block outbound HTTP.

Code Signing certificates for Azure Key Vault

OV Code Signing

DigiCert

DigiCert CodeSign OV

OV

DigiCert OV Code Signing. Works with Azure Key Vault.

from €475 /year See details →
GlobalSign

GlobalSign CodeSign

OV

GlobalSign OV Code Signing. Works with Azure Key Vault.

from €375 /year See details →

EV Code Signing

Frequently asked questions

Find answers to the most common questions about SSL certificates and FairSSL.

No. You can create a free Azure account and only pay for the Key Vault resource (~$5/month for Premium). If you already have an Azure subscription, you can create the Key Vault there.
No. The Standard SKU only supports software-protected keys. Code Signing requires HSM-backed keys (RSA-HSM), which are only available in the Premium tier.
Azure Key Vault uses a separate RBAC model for data plane operations. Having Contributor or Owner on the subscription does not automatically grant access to keys and certificates inside the vault. You need explicit Key Vault data plane roles.
Yes. If your signing process runs on Azure infrastructure (Azure DevOps hosted agents, Azure VMs, Azure Container Instances), you can use a managed identity for keyless authentication. This is more secure than client secrets.
With DigiCert, you can re-issue to the same key. Generate a new CSR from Key Vault and submit it to FairSSL for renewal. With GlobalSign, renewal requires a new order. In both cases, your Key Vault and signing configuration remain the same.
Yes. You can store multiple certificates in a single Key Vault. Each certificate has its own key pair and name. This is useful if you have separate certificates for different products or teams.

Ready to sign from Azure Key Vault?

Create a free account and issue your first certificate in under 10 minutes.