Azure Key Vault Certificate Commands

Comprehensive guide to managing SSL/TLS certificates using Azure Key Vault and the Azure CLI, including creation, import, policy management, and service integration.

🔧 Setup and Prerequisites

Install Azure CLI and create Key Vault

# Install Azure CLI (macOS)
brew install azure-cli

# Install Azure CLI (Linux)
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash

# Login to Azure
az login

# Set subscription
az account set --subscription "SUBSCRIPTION_ID"

# Create a resource group
az group create --name myResourceGroup --location eastus

# Create a Key Vault
az keyvault create \
  --name mykeyvault \
  --resource-group myResourceGroup \
  --location eastus \
  --sku standard

# Create Key Vault with RBAC authorization (recommended)
az keyvault create \
  --name mykeyvault \
  --resource-group myResourceGroup \
  --location eastus \
  --enable-rbac-authorization true

Key Vault names must be globally unique. The "standard" SKU uses software-protected keys; use "premium" for HSM-backed keys.

Configure access policies

# Grant certificate permissions to a user (access policy model)
az keyvault set-policy \
  --name mykeyvault \
  --upn [email protected] \
  --certificate-permissions get list create import delete update

# Grant certificate permissions to a service principal
az keyvault set-policy \
  --name mykeyvault \
  --spn "SERVICE_PRINCIPAL_APP_ID" \
  --certificate-permissions get list

# Grant RBAC role (RBAC model)
az role assignment create \
  --role "Key Vault Certificates Officer" \
  --assignee [email protected] \
  --scope /subscriptions/SUB_ID/resourceGroups/myResourceGroup/providers/Microsoft.KeyVault/vaults/mykeyvault

Choose either access policies or Azure RBAC. RBAC provides finer-grained control and is recommended for new deployments.

📜 Creating Certificates

Create self-signed certificate with default policy

# Create using default policy (self-signed, 12-month, RSA 2048)
az keyvault certificate create \
  --vault-name mykeyvault \
  --name mycert \
  --policy "$(az keyvault certificate get-default-policy)"

The default policy creates a self-signed certificate with CN=CLIGetDefaultPolicy, valid for 12 months.

Create certificate with custom policy file

# Example custom policy (policy.json):
# {
#   "issuerParameters": { "name": "Self" },
#   "keyProperties": {
#     "exportable": true, "keySize": 4096,
#     "keyType": "RSA", "reuseKey": false
#   },
#   "secretProperties": {
#     "contentType": "application/x-pkcs12"
#   },
#   "x509CertificateProperties": {
#     "subject": "CN=example.com, O=My Organization, C=US",
#     "subjectAlternativeNames": {
#       "dnsNames": ["example.com", "www.example.com"]
#     },
#     "keyUsage": ["digitalSignature", "keyEncipherment"],
#     "validityInMonths": 24
#   },
#   "lifetimeActions": [{
#     "trigger": { "daysBeforeExpiry": 30 },
#     "action": { "actionType": "AutoRenew" }
#   }]
# }

# Create certificate with the custom policy
az keyvault certificate create \
  --vault-name mykeyvault \
  --name mycert \
  --policy @policy.json

Custom policies let you specify subject, SANs, key size, validity period, and auto-renewal triggers. Use contentType "application/x-pem-file" for PEM format output.

Create certificate with CA issuer

# Register a certificate issuer (e.g., DigiCert, GlobalSign)
az keyvault certificate issuer create \
  --vault-name mykeyvault \
  --issuer-name DigiCertIssuer \
  --provider-name DigiCert \
  --account-id "YOUR_DIGICERT_ACCOUNT_ID" \
  --password "YOUR_API_KEY"

# Create certificate policy referencing the issuer
# In policy.json, set: "issuerParameters": { "name": "DigiCertIssuer" }

# Create certificate (submits CSR to the CA)
az keyvault certificate create \
  --vault-name mykeyvault \
  --name my-ca-cert \
  --policy @ca-policy.json

Integrated CA issuers automate the CSR submission and certificate installation process. Supported providers include DigiCert and GlobalSign.

📥 Importing Certificates

Import PFX certificate

# Import PFX/PKCS#12 file
az keyvault certificate import \
  --vault-name mykeyvault \
  --name mycert \
  --file certificate.pfx \
  --password "pfx-password"

# Import PFX with tags
az keyvault certificate import \
  --vault-name mykeyvault \
  --name mycert \
  --file certificate.pfx \
  --password "pfx-password" \
  --tags env=production app=webserver

The PFX file must include the certificate and private key. Intermediate certificates in the PFX are stored as part of the secret.

Import PEM certificate

# Combine certificate and key into a single PEM file
cat certificate.crt private-key.pem > combined.pem

# Import PEM file (no password needed for unencrypted key)
az keyvault certificate import \
  --vault-name mykeyvault \
  --name mycert \
  --file combined.pem

The PEM file must contain both the certificate and the unencrypted private key. If the key is encrypted, decrypt it first with OpenSSL.

🔍 Viewing and Listing Certificates

List and describe certificates

# List all certificates in a vault
az keyvault certificate list --vault-name mykeyvault

# List with specific output columns
az keyvault certificate list --vault-name mykeyvault \
  --query "[].{Name:name, Expires:attributes.expires, Enabled:attributes.enabled}" \
  --output table

# Show certificate details
az keyvault certificate show \
  --vault-name mykeyvault \
  --name mycert

# Get certificate thumbprint
az keyvault certificate show \
  --vault-name mykeyvault \
  --name mycert \
  --query "x509ThumbprintHex" \
  --output tsv

# List certificate versions
az keyvault certificate list-versions \
  --vault-name mykeyvault \
  --name mycert

# Show a specific version
az keyvault certificate show \
  --vault-name mykeyvault \
  --name mycert \
  --version VERSION_ID

Each certificate update (renewal, reimport) creates a new version. The latest version is always returned by default.

View certificate policy

# Get the default certificate policy
az keyvault certificate get-default-policy

# Get policy for an existing certificate
az keyvault certificate show \
  --vault-name mykeyvault \
  --name mycert \
  --query "policy"

📤 Downloading and Exporting

Download certificate (public key only)

# Download certificate in DER format
az keyvault certificate download \
  --vault-name mykeyvault \
  --name mycert \
  --file mycert.cer \
  --encoding DER

# Download certificate in PEM format
az keyvault certificate download \
  --vault-name mykeyvault \
  --name mycert \
  --file mycert.pem \
  --encoding PEM

The download command exports only the public certificate, not the private key.

Export certificate with private key

# The private key is stored as a Key Vault secret with the same name
# Export as PFX (if secret content type is application/x-pkcs12)
az keyvault secret download \
  --vault-name mykeyvault \
  --name mycert \
  --file mycert.pfx \
  --encoding base64

# Export as PEM (if secret content type is application/x-pem-file)
az keyvault secret download \
  --vault-name mykeyvault \
  --name mycert \
  --file mycert.pem \
  --encoding utf-8

# Convert PFX to PEM using OpenSSL if needed
openssl pkcs12 -in mycert.pfx -out mycert.pem -nodes

Key Vault stores the certificate, private key, and any intermediates together as a secret. The secret content type determines the format (PFX or PEM). Requires secret get permission.

📝 CSR Generation and Merging

Generate CSR and merge signed certificate

# Step 1: Create certificate with "Unknown" issuer to generate CSR
# Use a policy with: "issuerParameters": { "name": "Unknown" }
az keyvault certificate create \
  --vault-name mykeyvault \
  --name my-csr-cert \
  --policy @csr-policy.json

# Step 2: Download the pending CSR
az keyvault certificate pending show \
  --vault-name mykeyvault \
  --name my-csr-cert \
  --query "csr" \
  --output tsv > mycert.csr

# Step 3: Submit CSR to your external CA and get the signed certificate

# Step 4: Merge the signed certificate back
az keyvault certificate pending merge \
  --vault-name mykeyvault \
  --name my-csr-cert \
  --file signed-cert.cer

The "Unknown" issuer tells Key Vault to generate a key pair and CSR but wait for you to provide the signed certificate. The private key stays in Key Vault and is never exported during this process.

Manage pending certificate operations

# Check pending operation status
az keyvault certificate pending show \
  --vault-name mykeyvault \
  --name my-csr-cert

# Cancel a pending operation
az keyvault certificate pending delete \
  --vault-name mykeyvault \
  --name my-csr-cert

🔄 Certificate Lifecycle

Delete, recover, and purge certificates

# Delete certificate (soft-delete keeps it recoverable)
az keyvault certificate delete \
  --vault-name mykeyvault \
  --name mycert

# List deleted certificates
az keyvault certificate list-deleted \
  --vault-name mykeyvault

# Recover a deleted certificate
az keyvault certificate recover \
  --vault-name mykeyvault \
  --name mycert

# Permanently purge a deleted certificate
az keyvault certificate purge \
  --vault-name mykeyvault \
  --name mycert

Soft-delete is enabled by default (retention period: 7-90 days). Purge protection can be enabled to prevent permanent deletion during the retention period.

Backup and restore certificates

# Backup a certificate (encrypted blob)
az keyvault certificate backup \
  --vault-name mykeyvault \
  --name mycert \
  --file mycert-backup.blob

# Restore a certificate to the same or different vault
az keyvault certificate restore \
  --vault-name mykeyvault \
  --file mycert-backup.blob

Backups are encrypted and can only be restored to a Key Vault in the same Azure subscription and geography. Includes all versions and the policy.

Configure certificate contacts

# Add certificate contacts (notified on lifecycle events)
az keyvault certificate contact add \
  --vault-name mykeyvault \
  --email [email protected] \
  --name "Admin" \
  --phone "555-0100"

# List certificate contacts
az keyvault certificate contact list --vault-name mykeyvault

# Delete a contact
az keyvault certificate contact delete \
  --vault-name mykeyvault \
  --email [email protected]

Contacts receive notifications for certificate lifecycle events such as expiration warnings and renewal completions.

☁️ Integration with Azure Services

Use certificate with App Service

# Grant App Service resource provider access to Key Vault
az keyvault set-policy \
  --name mykeyvault \
  --spn abfa0a7c-a6b6-4736-8310-5855508787cd \
  --secret-permissions get \
  --certificate-permissions get

# Import Key Vault certificate into App Service
az webapp config ssl import \
  --resource-group myResourceGroup \
  --name mywebapp \
  --key-vault mykeyvault \
  --key-vault-certificate-name mycert

# Bind certificate to custom domain
az webapp config ssl bind \
  --resource-group myResourceGroup \
  --name mywebapp \
  --certificate-thumbprint THUMBPRINT \
  --ssl-type SNI

The service principal ID above is the well-known App Service resource provider. App Service can auto-sync certificate renewals from Key Vault.

Use certificate with Application Gateway

# Create a user-assigned managed identity
az identity create \
  --resource-group myResourceGroup \
  --name appgw-identity

# Grant the identity access to Key Vault secrets
az keyvault set-policy \
  --name mykeyvault \
  --object-id "$(az identity show \
    --resource-group myResourceGroup \
    --name appgw-identity \
    --query principalId -o tsv)" \
  --secret-permissions get

# Reference Key Vault certificate in Application Gateway SSL config
az network application-gateway ssl-cert create \
  --resource-group myResourceGroup \
  --gateway-name myAppGateway \
  --name kv-cert \
  --key-vault-secret-id "$(az keyvault certificate show \
    --vault-name mykeyvault --name mycert \
    --query sid -o tsv)"

Application Gateway references the Key Vault secret ID and automatically picks up renewed certificates when the vault is updated.

🏛️ Certificate Issuers

Manage certificate issuers

# List registered issuers
az keyvault certificate issuer list --vault-name mykeyvault

# Show issuer details
az keyvault certificate issuer show \
  --vault-name mykeyvault \
  --issuer-name DigiCertIssuer

# Update issuer credentials
az keyvault certificate issuer update \
  --vault-name mykeyvault \
  --issuer-name DigiCertIssuer \
  --account-id "NEW_ACCOUNT_ID" \
  --password "NEW_API_KEY"

# Delete an issuer
az keyvault certificate issuer delete \
  --vault-name mykeyvault \
  --issuer-name DigiCertIssuer

Built-in issuer names: "Self" for self-signed certificates, "Unknown" for external CA (CSR workflow). Register other issuers (DigiCert, GlobalSign) for automated CA integration.

See Also

Important Notes

Soft Delete:

Key Vault soft-delete is enabled by default (7-90 day retention). Deleted certificates can be recovered or purged. Purge protection prevents permanent deletion during retention.

Access Control:

Use RBAC (recommended) or access policies. Key roles: "Key Vault Certificates Officer" for full management, "Key Vault Certificate User" for read operations.

Certificate as Secret:

Key Vault stores the full certificate bundle (cert + key + chain) as a secret with the same name. Downloading the secret gives you the private key; downloading the certificate gives only the public part.

Auto-Renewal:

Self-signed certificates and those with integrated CA issuers can auto-renew using lifetime actions in the policy. Set triggers for days before expiry or percentage of lifetime elapsed.

Integration Sync:

App Service and Application Gateway can reference Key Vault certificates and automatically sync renewed versions. This avoids manual certificate replacement.

Pricing:

Certificate operations are charged per 10,000 operations. Standard vaults use software keys; Premium vaults support HSM-backed keys for higher security.

Documentation:

Azure Key Vault Certificates: learn.microsoft.com/azure/key-vault/certificates

Azure CLI Key Vault reference: learn.microsoft.com/cli/azure/keyvault/certificate