Azure Key Vault: Store and Retrieve Secrets the Right Way
| Category | Recommendation |
|---|---|
| Security | Never store secrets in code or configuration files |
| Access Control | Use Azure AD service principals for application access |
| Cost | Standard tier sufficient for most use cases (~$0.03/10K operations) |
| Monitoring | Enable diagnostic logging for all Key Vault operations |
| Backup | Implement automated backup strategy for critical secrets |
TL;DR
- Azure Key Vault centralizes secret management with enterprise-grade security and access controls
- Use Azure CLI, PowerShell, or REST APIs to programmatically manage secrets instead of hardcoding credentials
- Service principals and managed identities provide secure, passwordless authentication for applications
- Enable soft delete and purge protection to prevent accidental data loss in production environments
- Monitor all Key Vault operations through Azure Monitor and diagnostic logs for security compliance
Introduction
Hardcoded passwords, API keys scattered across configuration files, and database connection strings stored in plain text—these are the hallmarks of a security nightmare waiting to happen. Azure Key Vault solves these problems by providing a centralized, secure service for managing secrets, keys, and certificates.
sequenceDiagram
participant App as App Service
participant AAD as Microsoft Entra ID
participant KV as Azure Key Vault
App->>AAD: Request token (managed identity)
AAD-->>App: Access token
App->>KV: GET /secrets/{name} (Bearer token)
KV-->>App: Secret value
This comprehensive azure key vault tutorial walks you through implementing proper secret management practices that eliminate security vulnerabilities while maintaining operational efficiency. You'll learn to store, retrieve, and rotate secrets programmatically, implement role-based access controls, and integrate Key Vault with your applications using industry best practices.
Whether you're migrating legacy applications to Azure or building cloud-native solutions, mastering Key Vault is essential for maintaining security compliance and protecting sensitive data. By the end of this guide, you'll have a production-ready Key Vault implementation that follows Microsoft's recommended security patterns.
Prerequisites
- Active Azure subscription with Contributor access
- Azure CLI 2.30+ or Azure PowerShell 6.0+ installed locally
- Basic understanding of Azure Resource Groups and Azure Active Directory
- Familiarity with JSON and REST API concepts
- Text editor or IDE for code examples
Setting Up Your Azure Key Vault
1. Create a Key Vault Using Azure CLI
First, establish the foundation by creating a Resource Group and Key Vault instance:
# Set variables for consistent naming
RESOURCE_GROUP="rg-keyvault-demo"
KEY_VAULT_NAME="kv-demo-$(date +%s)" # Unique name with timestamp
LOCATION="eastus"
# Create resource group
az group create \
--name $RESOURCE_GROUP \
--location $LOCATION
# Create Key Vault with essential security features
az keyvault create \
--name $KEY_VAULT_NAME \
--resource-group $RESOURCE_GROUP \
--location $LOCATION \
--enable-soft-delete true \
--enable-purge-protection true \
--retention-days 90
2. Configure Access Policies
Key Vault uses access policies to control who can perform specific operations:
# Get your current user's object ID
USER_OBJECT_ID=$(az ad signed-in-user show --query id --output tsv)
# Grant yourself full permissions (development only)
az keyvault set-policy \
--name $KEY_VAULT_NAME \
--object-id $USER_OBJECT_ID \
--secret-permissions get list set delete backup restore recover purge
3. Alternative Setup Using PowerShell
If you prefer PowerShell, here's the equivalent setup:
# Connect to Azure
Connect-AzAccount
# Set variables
$ResourceGroup = "rg-keyvault-demo"
$KeyVaultName = "kv-demo-$(Get-Date -Format 'yyyyMMddHHmmss')"
$Location = "East US"
# Create resource group
New-AzResourceGroup -Name $ResourceGroup -Location $Location
# Create Key Vault
New-AzKeyVault `
-Name $KeyVaultName `
-ResourceGroupName $ResourceGroup `
-Location $Location `
-EnableSoftDelete `
-EnablePurgeProtection `
-SoftDeleteRetentionInDays 90
# Set access policy for current user
Set-AzKeyVaultAccessPolicy `
-VaultName $KeyVaultName `
-UserPrincipalName (Get-AzContext).Account.Id `
-PermissionsToSecrets get,list,set,delete,backup,restore,recover,purge
Managing Secrets in Key Vault
4. Store Secrets Securely
Never store secrets in plain text. Here are the proper methods for secret creation:
# Store a database connection string
az keyvault secret set \
--vault-name $KEY_VAULT_NAME \
--name "DatabaseConnectionString" \
--value "Server=myserver.database.windows.net;Database=mydb;User Id=admin;Password=SecureP@ss123;"
# Store an API key with expiration date
az keyvault secret set \
--vault-name $KEY_VAULT_NAME \
--name "ExternalAPIKey" \
--value "sk-1234567890abcdef" \
--expires "2024-12-31T23:59:59Z"
# Store a secret from file (recommended for certificates)
echo "MySecretValue123!" > temp_secret.txt
az keyvault secret set \
--vault-name $KEY_VAULT_NAME \
--name "ApplicationSecret" \
--file temp_secret.txt
rm temp_secret.txt
5. Retrieve Secrets Programmatically
Applications should retrieve secrets at runtime, not during build:
# Retrieve secret value
SECRET_VALUE=$(az keyvault secret show \
--vault-name $KEY_VAULT_NAME \
--name "DatabaseConnectionString" \
--query value \
--output tsv)
echo "Retrieved secret: $SECRET_VALUE"
# List all secrets (shows names only, not values)
az keyvault secret list \
--vault-name $KEY_VAULT_NAME \
--output table
6. Secret Versioning and Rotation
Key Vault automatically versions secrets, enabling safe rotation:
# Update an existing secret (creates new version)
az keyvault secret set \
--vault-name $KEY_VAULT_NAME \
--name "ExternalAPIKey" \
--value "sk-newkey9876543210"
# Retrieve specific version
az keyvault secret show \
--vault-name $KEY_VAULT_NAME \
--name "ExternalAPIKey" \
--version "previous-version-id" \
--query value \
--output tsv
# List all versions of a secret
az keyvault secret list-versions \
--vault-name $KEY_VAULT_NAME \
--name "ExternalAPIKey" \
--output table
Application Integration Best Practices
7. Service Principal Authentication
Create a service principal for application authentication:
# Create service principal
SP_NAME="sp-keyvault-app"
SP_CREDENTIALS=$(az ad sp create-for-rbac \
--name $SP_NAME \
--role Reader \
--scopes /subscriptions/$(az account show --query id -o tsv)/resourceGroups/$RESOURCE_GROUP)
# Extract service principal details
SP_CLIENT_ID=$(echo $SP_CREDENTIALS | jq -r '.appId')
SP_CLIENT_SECRET=$(echo $SP_CREDENTIALS | jq -r '.password')
SP_OBJECT_ID=$(az ad sp show --id $SP_CLIENT_ID --query id --output tsv)
# Grant Key Vault access to service principal
az keyvault set-policy \
--name $KEY_VAULT_NAME \
--object-id $SP_OBJECT_ID \
--secret-permissions get list
echo "Service Principal Client ID: $SP_CLIENT_ID"
echo "Store the client secret securely: $SP_CLIENT_SECRET"
8. Python Application Example
Here's how to integrate Key Vault into a Python application:
from azure.identity import ClientSecretCredential
from azure.keyvault.secrets import SecretClient
import os
# Configuration (environment variables in production)
TENANT_ID = "your-tenant-id"
CLIENT_ID = "your-client-id"
CLIENT_SECRET = "your-client-secret"
VAULT_URL = f"https://{KEY_VAULT_NAME}.vault.azure.net/"
# Authenticate using service principal
credential = ClientSecretCredential(
tenant_id=TENANT_ID,
client_id=CLIENT_ID,
client_secret=CLIENT_SECRET
)
# Create Key Vault client
client = SecretClient(vault_url=VAULT_URL, credential=credential)
try:
# Retrieve secret
secret = client.get_secret("DatabaseConnectionString")
print(f"Retrieved secret version: {secret.properties.version}")
# Use secret value (never log it)
connection_string = secret.value
# Set new secret
client.set_secret("NewApplicationKey", "secure-value-123")
print("Secret stored successfully")
except Exception as e:
print(f"Error accessing Key Vault: {e}")
Advanced Configuration and Security
9. Network Security and Firewall Rules
Restrict Key Vault access to specific networks:
# Configure firewall rules (replace with your IP)
YOUR_PUBLIC_IP=$(curl -s https://ipinfo.io/ip)
az keyvault network-rule add \
--vault-name $KEY_VAULT_NAME \
--ip-address $YOUR_PUBLIC_IP
# Enable private endpoint for VNet access
az keyvault update \
--name $KEY_VAULT_NAME \
--default-action Deny \
--bypass AzureServices
10. Enable Monitoring and Logging
Set up comprehensive monitoring for security compliance:
# Create Log Analytics workspace
WORKSPACE_NAME="law-keyvault-logs"
az monitor log-analytics workspace create \
--resource-group $RESOURCE_GROUP \
--workspace-name $WORKSPACE_NAME
# Get workspace ID
WORKSPACE_ID=$(az monitor log-analytics workspace show \
--resource-group $RESOURCE_GROUP \
--workspace-name $WORKSPACE_NAME \
--query id --output tsv)
# Enable diagnostic settings
az monitor diagnostic-settings create \
--name "keyvault-diagnostics" \
--resource $KEY_VAULT_NAME \
--resource-group $RESOURCE_GROUP \
--resource-type "Microsoft.KeyVault/vaults" \
--workspace $WORKSPACE_ID \
--logs '[{"category":"AuditEvent","enabled":true}]' \
--metrics '[{"category":"AllMetrics","enabled":true}]'
Troubleshooting Common Issues
Access Denied Errors
Problem: The user, group or application does not have permission to perform operation
Solution:
# Check current access policies
az keyvault show --name $KEY_VAULT_NAME --query properties.accessPolicies
# Verify your permissions
az keyvault secret list --vault-name $KEY_VAULT_NAME --output table
Network Connectivity Issues
Problem: Host not found or timeout errors
Solution:
# Test connectivity
nslookup $KEY_VAULT_NAME.vault.azure.net
# Check firewall rules
az keyvault network-rule list --vault-name $KEY_VAULT_NAME
Authentication Failures
Problem: Service principal authentication failing
Solution:
# Verify service principal exists
az ad sp show --id $SP_CLIENT_ID
# Test authentication manually
az login --service-principal \
--username $SP_CLIENT_ID \
--password $SP_CLIENT_SECRET \
--tenant $TENANT_ID
Common Mistakes to Avoid
- Storing secrets in application code: Always retrieve secrets at runtime from Key Vault
- Using overly permissive access policies: Grant minimum required permissions only
- Ignoring secret expiration: Implement automated rotation for time-sensitive credentials
- Disabling soft delete: Always enable soft delete and purge protection in production
- Not monitoring access: Enable diagnostic logging to track all Key Vault operations
- Hardcoding Key Vault names: Use environment variables or configuration files for vault URLs
Key Takeaways
- Azure Key Vault centralizes secret management with enterprise-grade security features including encryption at rest and in transit
- Service principals provide secure authentication for applications without exposing user credentials or requiring interactive login
- Access policies enable granular permission control allowing you to grant specific operations (get, set, delete) to different users and applications
- Secret versioning supports safe rotation by maintaining previous versions while updating credentials in production systems
- Monitoring and logging are essential for security compliance and should be configured from the beginning, not as an afterthought
- Network restrictions enhance security by limiting Key Vault access to authorized IP addresses and virtual networks
- Soft delete and purge protection prevent accidental data loss and should be enabled on all production Key Vault instances
Next Steps
Now that you've mastered basic Key Vault operations, consider these advanced topics:
- Implement Azure Key Vault with Azure DevOps for secure CI/CD pipeline secret management
- Explore Key Vault integration with Azure Kubernetes Service using the CSI Secrets Store driver
- Set up automated secret rotation using Azure Functions and Key Vault events
Leave a Reply