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
Figure: Passwordless secret retrieval using a managed identity and Microsoft Entra ID.

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:

  1. Implement Azure Key Vault with Azure DevOps for secure CI/CD pipeline secret management
  2. Explore Key Vault integration with Azure Kubernetes Service using the CSI Secrets Store driver
  3. Set up automated secret rotation using Azure Functions and Key Vault events

Related Articles

Thorsteinn Halldorsson Senior Cloud Engineer

Senior Cloud Engineer with 25+ years of hands-on experience across the datacenter-to-cloud stack: fiber SAN and disk storage, IBM/Lenovo blade and Dell/HP/Lenovo servers, Hyper-V and VMware clusters, and SQL and Remote Desktop Services (RDS) clusters. Deep in the Microsoft platform — Active Directory, PKI/certificate services, SQL, Power BI, Dynamics 365 Business Central (NAV) and AX (Axapta), Microsoft 365, Entra, and Intune — with a focus on Azure operations, FinOps, and applying AI tools like GitHub Copilot and Claude in real workflows. Writes practical, no-nonsense guides for IT professionals who need to ship real solutions.

Leave a Reply

Your email address will not be published. Required fields are marked *