Azure Key Vault: Complete Security Management Cheat Sheet

Introduction

Azure Key Vault is a cloud service for securely storing and accessing secrets, keys, and certificates. It provides a centralized solution for storing sensitive information such as API keys, passwords, certificates, and cryptographic keys while enforcing strict access policies. Key Vault helps maintain control of sensitive data by ensuring that secrets don’t leave Azure’s security boundaries, providing logging capabilities, and simplifying administration of application secrets.

Core Concepts

ConceptDescription
Key VaultA logical group of secrets, keys, and certificates with shared access policies
SecretAny sensitive text data (passwords, connection strings, API keys)
KeyCryptographic keys for encryption operations
CertificateX.509 certificates with optional private key
Soft DeleteTemporary retention of deleted vaults and objects
Purge ProtectionPrevention of permanent deletion of deleted vaults and objects
Access PolicyControls permissions for each principal (user, service principal, managed identity)
RBACAzure role-based access control
HSMHardware Security Module for key storage (Premium tier)

Key Vault Types and SKUs

SKUFeaturesUse Cases
StandardSoftware-protected keys, secrets, certificatesGeneral purpose protection
PremiumHSM-protected keys + Standard featuresRegulatory compliance, high-security needs

Authentication Methods

MethodDescriptionBest For
Service PrincipalUses app registration with secret or certificateLegacy applications
Managed IdentitySystem or user-assigned identityModern Azure services
User IdentityAzure AD user authenticationDevelopment, administration
Key Vault ReferencesService-specific integration (App Service)PaaS services with native support

Creating and Managing a Key Vault

Azure Portal

  1. Navigate to Key Vaults service
  2. Click Create
  3. Fill in Basics:
    • Project details (subscription, resource group)
    • Instance details (name, region, pricing tier)
  4. Configure Access policy (or use RBAC model)
  5. Set Networking (public, private, or selected networks)
  6. Add Tags if needed
  7. Click Review + create

Azure CLI

# Create a Key Vault
az keyvault create \
  --name "MyKeyVault" \
  --resource-group "MyResourceGroup" \
  --location "EastUS" \
  --enabled-for-disk-encryption true \
  --enabled-for-deployment true \
  --enabled-for-template-deployment true \
  --sku "standard"

# Set access policy
az keyvault set-policy \
  --name "MyKeyVault" \
  --resource-group "MyResourceGroup" \
  --object-id "user-or-app-object-id" \
  --secret-permissions get list set delete backup restore recover purge \
  --key-permissions get list create delete import update backup restore recover purge \
  --certificate-permissions get list create delete import update backup restore recover purge

# Enable soft-delete and purge protection
az keyvault update \
  --name "MyKeyVault" \
  --resource-group "MyResourceGroup" \
  --enable-soft-delete true \
  --enable-purge-protection true

Azure PowerShell

# Create a Key Vault
New-AzKeyVault `
  -Name "MyKeyVault" `
  -ResourceGroupName "MyResourceGroup" `
  -Location "EastUS" `
  -EnabledForDiskEncryption `
  -EnabledForDeployment `
  -EnabledForTemplateDeployment `
  -Sku "Standard"

# Set access policy
Set-AzKeyVaultAccessPolicy `
  -VaultName "MyKeyVault" `
  -ResourceGroupName "MyResourceGroup" `
  -ObjectId "user-or-app-object-id" `
  -PermissionsToSecrets Get,List,Set,Delete,Backup,Restore,Recover,Purge `
  -PermissionsToKeys Get,List,Create,Delete,Import,Update,Backup,Restore,Recover,Purge `
  -PermissionsToCertificates Get,List,Create,Delete,Import,Update,Backup,Restore,Recover,Purge

# Enable soft-delete and purge protection
Update-AzKeyVault `
  -VaultName "MyKeyVault" `
  -ResourceGroupName "MyResourceGroup" `
  -EnableSoftDelete $true `
  -EnablePurgeProtection $true

ARM Template

{
  "type": "Microsoft.KeyVault/vaults",
  "apiVersion": "2022-07-01",
  "name": "MyKeyVault",
  "location": "[resourceGroup().location]",
  "properties": {
    "enabledForDeployment": true,
    "enabledForDiskEncryption": true,
    "enabledForTemplateDeployment": true,
    "tenantId": "[subscription().tenantId]",
    "accessPolicies": [
      {
        "tenantId": "[subscription().tenantId]",
        "objectId": "user-or-app-object-id",
        "permissions": {
          "keys": ["Get", "List", "Create", "Delete", "Update", "Import", "Backup", "Restore", "Recover"],
          "secrets": ["Get", "List", "Set", "Delete", "Backup", "Restore", "Recover"],
          "certificates": ["Get", "List", "Create", "Delete", "Update", "Import", "Backup", "Restore", "Recover"]
        }
      }
    ],
    "sku": {
      "name": "standard",
      "family": "A"
    },
    "softDeleteRetentionInDays": 90,
    "enableSoftDelete": true,
    "enablePurgeProtection": true,
    "networkAcls": {
      "defaultAction": "Deny",
      "bypass": "AzureServices",
      "ipRules": [],
      "virtualNetworkRules": []
    }
  }
}

Working with Secrets

Azure CLI

# Create a secret
az keyvault secret set \
  --vault-name "MyKeyVault" \
  --name "MySecret" \
  --value "MySecretValue"

# Get a secret
az keyvault secret show \
  --vault-name "MyKeyVault" \
  --name "MySecret"

# List secrets
az keyvault secret list \
  --vault-name "MyKeyVault"

# Delete a secret (soft-delete)
az keyvault secret delete \
  --vault-name "MyKeyVault" \
  --name "MySecret"

# Recover a deleted secret
az keyvault secret recover \
  --vault-name "MyKeyVault" \
  --name "MySecret"

# Permanently delete a secret (if purge protection is not enabled)
az keyvault secret purge \
  --vault-name "MyKeyVault" \
  --name "MySecret"

PowerShell

# Create a secret
Set-AzKeyVaultSecret `
  -VaultName "MyKeyVault" `
  -Name "MySecret" `
  -SecretValue (ConvertTo-SecureString -String "MySecretValue" -AsPlainText -Force)

# Get a secret
Get-AzKeyVaultSecret `
  -VaultName "MyKeyVault" `
  -Name "MySecret"

# List secrets
Get-AzKeyVaultSecret `
  -VaultName "MyKeyVault"

# Delete a secret (soft-delete)
Remove-AzKeyVaultSecret `
  -VaultName "MyKeyVault" `
  -Name "MySecret"

# Recover a deleted secret
Undo-AzKeyVaultSecretRemoval `
  -VaultName "MyKeyVault" `
  -Name "MySecret"

# Permanently delete a secret (if purge protection is not enabled)
Remove-AzKeyVaultSecret `
  -VaultName "MyKeyVault" `
  -Name "MySecret" `
  -InRemovedState

Working with Keys

Azure CLI

# Create a key (software-protected)
az keyvault key create \
  --vault-name "MyKeyVault" \
  --name "MyKey" \
  --protection software

# Create an HSM-protected key (Premium tier only)
az keyvault key create \
  --vault-name "MyKeyVault" \
  --name "MyHsmKey" \
  --protection hsm

# Import a key from a PFX file
az keyvault key import \
  --vault-name "MyKeyVault" \
  --name "ImportedKey" \
  --pem-file "/path/to/key.pem" \
  --pem-password "PfxPassword"

# Get a key
az keyvault key show \
  --vault-name "MyKeyVault" \
  --name "MyKey"

# List keys
az keyvault key list \
  --vault-name "MyKeyVault"

# Update key attributes
az keyvault key set-attributes \
  --vault-name "MyKeyVault" \
  --name "MyKey" \
  --enabled true \
  --expires "2025-12-31T23:59:59Z"

# Delete a key (soft-delete)
az keyvault key delete \
  --vault-name "MyKeyVault" \
  --name "MyKey"

PowerShell

# Create a key (software-protected)
Add-AzKeyVaultKey `
  -VaultName "MyKeyVault" `
  -Name "MyKey" `
  -Destination "Software"

# Create an HSM-protected key (Premium tier only)
Add-AzKeyVaultKey `
  -VaultName "MyKeyVault" `
  -Name "MyHsmKey" `
  -Destination "HSM"

# Import a key from a PFX file
$securePassword = ConvertTo-SecureString -String "PfxPassword" -AsPlainText -Force
Import-AzKeyVaultKey `
  -VaultName "MyKeyVault" `
  -Name "ImportedKey" `
  -KeyFilePath "/path/to/key.pfx" `
  -KeyFilePassword $securePassword

# Get a key
Get-AzKeyVaultKey `
  -VaultName "MyKeyVault" `
  -Name "MyKey"

# List keys
Get-AzKeyVaultKey `
  -VaultName "MyKeyVault"

# Update key attributes
Update-AzKeyVaultKey `
  -VaultName "MyKeyVault" `
  -Name "MyKey" `
  -Expires (Get-Date).AddYears(1)

# Delete a key (soft-delete)
Remove-AzKeyVaultKey `
  -VaultName "MyKeyVault" `
  -Name "MyKey"

Working with Certificates

Azure CLI

# Create a self-signed certificate
az keyvault certificate create \
  --vault-name "MyKeyVault" \
  --name "MyCertificate" \
  --policy "@policy.json"

# Import a certificate
az keyvault certificate import \
  --vault-name "MyKeyVault" \
  --name "ImportedCert" \
  --file "/path/to/cert.pfx" \
  --password "CertPassword"

# Get a certificate
az keyvault certificate show \
  --vault-name "MyKeyVault" \
  --name "MyCertificate"

# List certificates
az keyvault certificate list \
  --vault-name "MyKeyVault"

# Delete a certificate (soft-delete)
az keyvault certificate delete \
  --vault-name "MyKeyVault" \
  --name "MyCertificate"

PowerShell

# Create a self-signed certificate
$policy = New-AzKeyVaultCertificatePolicy `
  -SecretContentType "application/x-pkcs12" `
  -SubjectName "CN=example.com" `
  -IssuerName "Self" `
  -ValidityInMonths 12 `
  -ReuseKeyOnRenewal $true

Add-AzKeyVaultCertificate `
  -VaultName "MyKeyVault" `
  -Name "MyCertificate" `
  -CertificatePolicy $policy

# Import a certificate
$securePassword = ConvertTo-SecureString -String "CertPassword" -AsPlainText -Force
Import-AzKeyVaultCertificate `
  -VaultName "MyKeyVault" `
  -Name "ImportedCert" `
  -FilePath "/path/to/cert.pfx" `
  -Password $securePassword

# Get a certificate
Get-AzKeyVaultCertificate `
  -VaultName "MyKeyVault" `
  -Name "MyCertificate"

# List certificates
Get-AzKeyVaultCertificate `
  -VaultName "MyKeyVault"

# Delete a certificate (soft-delete)
Remove-AzKeyVaultCertificate `
  -VaultName "MyKeyVault" `
  -Name "MyCertificate"

Certificate Policy JSON Example

{
  "issuerParameters": {
    "name": "Self"
  },
  "keyProperties": {
    "exportable": true,
    "keySize": 2048,
    "keyType": "RSA",
    "reuseKey": true
  },
  "secretProperties": {
    "contentType": "application/x-pkcs12"
  },
  "x509CertificateProperties": {
    "keyUsage": [
      "digitalSignature",
      "keyEncipherment"
    ],
    "subject": "CN=example.com",
    "validityInMonths": 12,
    "subjectAlternativeNames": {
      "dnsNames": [
        "example.com",
        "www.example.com"
      ]
    }
  }
}

Integrating Key Vault with Applications

.NET Application

// Install packages:
// Microsoft.Azure.KeyVault
// Microsoft.Azure.Services.AppAuthentication
// Microsoft.Extensions.Configuration.AzureKeyVault

// Program.cs
public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((context, config) =>
        {
            var settings = config.Build();
            var keyVaultName = settings["KeyVaultName"];
            var keyVaultUri = $"https://{keyVaultName}.vault.azure.net/";
            
            var azureServiceTokenProvider = new AzureServiceTokenProvider();
            var keyVaultClient = new KeyVaultClient(
                new KeyVaultClient.AuthenticationCallback(
                    azureServiceTokenProvider.KeyVaultTokenCallback));
                    
            config.AddAzureKeyVault(keyVaultUri, keyVaultClient, new DefaultKeyVaultSecretManager());
        })
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

// Usage
public class MyService
{
    private readonly string _connectionString;
    
    public MyService(IConfiguration configuration)
    {
        _connectionString = configuration["MySecret"];
    }
}

Node.js Application

// Install packages:
// npm install @azure/identity @azure/keyvault-secrets

const { DefaultAzureCredential } = require('@azure/identity');
const { SecretClient } = require('@azure/keyvault-secrets');

async function getSecret() {
  // Create a credential using Managed Identity or other auth methods
  const credential = new DefaultAzureCredential();
  
  // Key Vault URL format: https://<key-vault-name>.vault.azure.net
  const vaultUrl = "https://mykeyvault.vault.azure.net";
  const client = new SecretClient(vaultUrl, credential);
  
  // Get the secret
  const secret = await client.getSecret("MySecret");
  return secret.value;
}

// Usage
getSecret()
  .then(secretValue => {
    console.log(`Secret value: ${secretValue}`);
  })
  .catch(error => {
    console.error(`Error getting secret: ${error}`);
  });

Python Application

# Install packages:
# pip install azure-identity azure-keyvault-secrets

from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient

def get_secret():
    # Create a credential using Managed Identity or other auth methods
    credential = DefaultAzureCredential()
    
    # Key Vault URL format: https://<key-vault-name>.vault.azure.net
    vault_url = "https://mykeyvault.vault.azure.net"
    client = SecretClient(vault_url=vault_url, credential=credential)
    
    # Get the secret
    secret = client.get_secret("MySecret")
    return secret.value

# Usage
try:
    secret_value = get_secret()
    print(f"Secret value: {secret_value}")
except Exception as ex:
    print(f"Error getting secret: {ex}")

Azure App Service Integration

  1. Enable Managed Identity for App Service
  2. Grant the Managed Identity access to Key Vault
  3. Reference Key Vault secrets directly in configuration
// appsettings.json
{
  "ConnectionStrings": {
    "MyDatabase": "@Microsoft.KeyVault(SecretUri=https://mykeyvault.vault.azure.net/secrets/MyDbConnection/)"
  }
}

Security Best Practices

Best PracticeDescription
Use Managed IdentitiesAvoid storing credentials, use Azure AD authentication
Enable Soft-DeleteProtect against accidental deletion with recovery options
Enable Purge ProtectionPrevent permanent deletion during retention period
Implement RBACUse role-based access control over access policies
Network RestrictionsRestrict network access to trusted networks
Private EndpointUse private link for secure private network access
Monitor AccessEnable diagnostic logs and Azure Monitor
Rotate Secrets RegularlyImplement a rotation strategy for secrets
Use HSM-backed KeysFor high-security scenarios (Premium tier)
Separate Development/ProductionUse different Key Vaults for each environment

Access Control and RBAC

Built-in RoleDescription
Key Vault AdministratorFull access to manage all Key Vault operations
Key Vault Certificates OfficerPerform certificate management operations
Key Vault Crypto OfficerPerform cryptographic key operations
Key Vault Crypto Service Encryption UserRead metadata and use keys for encryption/decryption
Key Vault Crypto UserPerform cryptographic operations using keys
Key Vault ReaderRead-only access to vault metadata
Key Vault Secrets OfficerPerform secret management operations
Key Vault Secrets UserRead secret contents

Assigning RBAC Roles (Azure CLI)

# Assign Key Vault Secrets Officer role
az role assignment create \
  --role "Key Vault Secrets Officer" \
  --assignee "user-or-app-object-id" \
  --scope "/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.KeyVault/vaults/<key-vault-name>"

Assigning RBAC Roles (PowerShell)

# Assign Key Vault Secrets Officer role
New-AzRoleAssignment `
  -RoleDefinitionName "Key Vault Secrets Officer" `
  -ObjectId "user-or-app-object-id" `
  -Scope "/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.KeyVault/vaults/<key-vault-name>"

Monitoring and Logging

Enable Diagnostic Settings

# Azure CLI
az monitor diagnostic-settings create \
  --name "KeyVaultLogs" \
  --resource "MyKeyVault" \
  --resource-group "MyResourceGroup" \
  --resource-type "Microsoft.KeyVault/vaults" \
  --logs '[{"category": "AuditEvent","enabled": true}]' \
  --metrics '[{"category": "AllMetrics","enabled": true}]' \
  --workspace "MyLogAnalyticsWorkspace"
# PowerShell
Set-AzDiagnosticSetting `
  -Name "KeyVaultLogs" `
  -ResourceId "/subscriptions/<subscription-id>/resourceGroups/MyResourceGroup/providers/Microsoft.KeyVault/vaults/MyKeyVault" `
  -WorkspaceId "/subscriptions/<subscription-id>/resourcegroups/MyResourceGroup/providers/microsoft.operationalinsights/workspaces/MyLogAnalyticsWorkspace" `
  -Enabled $true `
  -Category "AuditEvent" `
  -MetricCategory "AllMetrics"

Key Audit Log Events

Operation CategoryDescription
AdministrativeCreate/Delete/Update vault
CryptographicOperationsEncrypt/Decrypt/Sign/Verify
KeyOperationsCreate/Import/Delete/Update keys
SecretOperationsCreate/Delete/Update/Get secrets
CertificateOperationsCreate/Import/Delete/Update certificates

Common Log Analytics Queries

// All Key Vault operations in the last 24 hours
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.KEYVAULT"
| where TimeGenerated > ago(24h)
| project TimeGenerated, OperationName, ResultType, ResultSignature, CallerIPAddress

// Failed operations in the last 7 days
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.KEYVAULT"
| where TimeGenerated > ago(7d)
| where ResultType != "Success"
| project TimeGenerated, OperationName, ResultType, ResultSignature, CallerIPAddress, Resource

// All secret retrievals in the last 24 hours
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.KEYVAULT"
| where OperationName == "SecretGet" or OperationName == "SecretList"
| where TimeGenerated > ago(24h)
| project TimeGenerated, OperationName, id_s, CallerIPAddress, identity_claim_appid_g

Key Vault Recovery

Recovering Deleted Key Vault

# List deleted Key Vaults
az keyvault list-deleted --query "[].{Name:name,Location:properties.location}" -o table

# Recover a deleted Key Vault
az keyvault recover --name "MyKeyVault"

# Purge a deleted Key Vault (if purge protection is not enabled)
az keyvault purge --name "MyKeyVault"
# List deleted Key Vaults
Get-AzKeyVault -InRemovedState

# Recover a deleted Key Vault
Undo-AzKeyVaultRemoval -VaultName "MyKeyVault" -ResourceGroupName "MyResourceGroup" -Location "EastUS"

# Purge a deleted Key Vault (if purge protection is not enabled)
Remove-AzKeyVault -VaultName "MyKeyVault" -InRemovedState -Location "EastUS"

Key Vault Backup and Restore

Backing Up Secrets, Keys, and Certificates

# Backup a secret
az keyvault secret backup \
  --vault-name "MyKeyVault" \
  --name "MySecret" \
  --file "mysecret.backup"

# Backup a key
az keyvault key backup \
  --vault-name "MyKeyVault" \
  --name "MyKey" \
  --file "mykey.backup"

# Backup a certificate
az keyvault certificate backup \
  --vault-name "MyKeyVault" \
  --name "MyCertificate" \
  --file "mycert.backup"
# Backup a secret
Backup-AzKeyVaultSecret `
  -VaultName "MyKeyVault" `
  -Name "MySecret" `
  -OutputFile "mysecret.backup"

# Backup a key
Backup-AzKeyVaultKey `
  -VaultName "MyKeyVault" `
  -Name "MyKey" `
  -OutputFile "mykey.backup"

# Backup a certificate
Backup-AzKeyVaultCertificate `
  -VaultName "MyKeyVault" `
  -Name "MyCertificate" `
  -OutputFile "mycert.backup"

Restoring Secrets, Keys, and Certificates

# Restore a secret
az keyvault secret restore \
  --vault-name "MyKeyVault" \
  --file "mysecret.backup"

# Restore a key
az keyvault key restore \
  --vault-name "MyKeyVault" \
  --file "mykey.backup"

# Restore a certificate
az keyvault certificate restore \
  --vault-name "MyKeyVault" \
  --file "mycert.backup"
# Restore a secret
Restore-AzKeyVaultSecret `
  -VaultName "MyKeyVault" `
  -InputFile "mysecret.backup"

# Restore a key
Restore-AzKeyVaultKey `
  -VaultName "MyKeyVault" `
  -InputFile "mykey.backup"

# Restore a certificate
Restore-AzKeyVaultCertificate `
  -VaultName "MyKeyVault" `
  -InputFile "mycert.backup"

Key Vault Automation and DevOps

Using Key Vault in Azure DevOps

  1. Create a Service Connection to Azure
  2. Use Variable Groups linked to Key Vault
  3. Access secrets during pipeline execution
# azure-pipelines.yml
variables:
- group: MyKeyVaultVariables

steps:
- task: AzureKeyVault@2
  inputs:
    azureSubscription: 'MyAzureConnection'
    KeyVaultName: 'MyKeyVault'
    SecretsFilter: 'MySecret'
    RunAsPreJob: true

- script: |
    echo "Using secret: $(MySecret)"
  displayName: 'Use Key Vault secret'

Using Key Vault in GitHub Actions

# github-workflow.yml
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: azure/login@v1
      with:
        creds: ${{ secrets.AZURE_CREDENTIALS }}
        
    - uses: azure/get-keyvault-secrets@v1
      with:
        keyvault: "MyKeyVault"
        secrets: "MySecret"
      id: mySecret
      
    - name: Use Secret
      run: |
        echo "Using secret: ${{ steps.mySecret.outputs.MySecret }}"

Common Troubleshooting

IssuePossible CauseSolution
Access DeniedMissing permissionsCheck access policies/RBAC roles
Forbidden (403)Network restrictionsCheck firewall settings, private endpoints
Not Found (404)Incorrect Key Vault nameVerify the Key Vault exists and name is correct
Certificate Policy IssueInvalid certificate policyCheck policy JSON format and parameters
Throttling (429)Rate limits exceededImplement retry logic, reduce frequency
ServiceUnavailable (503)Azure service issuesCheck Azure status, implement retry logic

Resources for Further Learning

This comprehensive Azure Key Vault cheat sheet provides a quick reference for developers and administrators working with Azure’s secure secret, key, and certificate management service. From basic concepts to advanced security practices, use this guide to implement robust security for your cloud applications.

Scroll to Top