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
Concept | Description |
---|
Key Vault | A logical group of secrets, keys, and certificates with shared access policies |
Secret | Any sensitive text data (passwords, connection strings, API keys) |
Key | Cryptographic keys for encryption operations |
Certificate | X.509 certificates with optional private key |
Soft Delete | Temporary retention of deleted vaults and objects |
Purge Protection | Prevention of permanent deletion of deleted vaults and objects |
Access Policy | Controls permissions for each principal (user, service principal, managed identity) |
RBAC | Azure role-based access control |
HSM | Hardware Security Module for key storage (Premium tier) |
Key Vault Types and SKUs
SKU | Features | Use Cases |
---|
Standard | Software-protected keys, secrets, certificates | General purpose protection |
Premium | HSM-protected keys + Standard features | Regulatory compliance, high-security needs |
Authentication Methods
Method | Description | Best For |
---|
Service Principal | Uses app registration with secret or certificate | Legacy applications |
Managed Identity | System or user-assigned identity | Modern Azure services |
User Identity | Azure AD user authentication | Development, administration |
Key Vault References | Service-specific integration (App Service) | PaaS services with native support |
Creating and Managing a Key Vault
Azure Portal
- Navigate to Key Vaults service
- Click Create
- Fill in Basics:
- Project details (subscription, resource group)
- Instance details (name, region, pricing tier)
- Configure Access policy (or use RBAC model)
- Set Networking (public, private, or selected networks)
- Add Tags if needed
- 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
- Enable Managed Identity for App Service
- Grant the Managed Identity access to Key Vault
- 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 Practice | Description |
---|
Use Managed Identities | Avoid storing credentials, use Azure AD authentication |
Enable Soft-Delete | Protect against accidental deletion with recovery options |
Enable Purge Protection | Prevent permanent deletion during retention period |
Implement RBAC | Use role-based access control over access policies |
Network Restrictions | Restrict network access to trusted networks |
Private Endpoint | Use private link for secure private network access |
Monitor Access | Enable diagnostic logs and Azure Monitor |
Rotate Secrets Regularly | Implement a rotation strategy for secrets |
Use HSM-backed Keys | For high-security scenarios (Premium tier) |
Separate Development/Production | Use different Key Vaults for each environment |
Access Control and RBAC
Built-in Role | Description |
---|
Key Vault Administrator | Full access to manage all Key Vault operations |
Key Vault Certificates Officer | Perform certificate management operations |
Key Vault Crypto Officer | Perform cryptographic key operations |
Key Vault Crypto Service Encryption User | Read metadata and use keys for encryption/decryption |
Key Vault Crypto User | Perform cryptographic operations using keys |
Key Vault Reader | Read-only access to vault metadata |
Key Vault Secrets Officer | Perform secret management operations |
Key Vault Secrets User | Read 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 Category | Description |
---|
Administrative | Create/Delete/Update vault |
CryptographicOperations | Encrypt/Decrypt/Sign/Verify |
KeyOperations | Create/Import/Delete/Update keys |
SecretOperations | Create/Delete/Update/Get secrets |
CertificateOperations | Create/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
- Create a Service Connection to Azure
- Use Variable Groups linked to Key Vault
- 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
Issue | Possible Cause | Solution |
---|
Access Denied | Missing permissions | Check access policies/RBAC roles |
Forbidden (403) | Network restrictions | Check firewall settings, private endpoints |
Not Found (404) | Incorrect Key Vault name | Verify the Key Vault exists and name is correct |
Certificate Policy Issue | Invalid certificate policy | Check policy JSON format and parameters |
Throttling (429) | Rate limits exceeded | Implement retry logic, reduce frequency |
ServiceUnavailable (503) | Azure service issues | Check 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.