Overview and What You Will Learn
In this lab, you will create a Key Vault, store a secret in it, then grant a VM's Managed Identity permission to read that secret - so the application running on that VM can retrieve a credential at runtime without any secret ever being written into its own configuration file or source code.
Why This Matters in Production
A developer at a fintech startup hardcodes a database password directly into an application's config file, commits it to source control, and six months later that repository becomes public by accident. Every credential inside it is now compromised. Azure Key Vault exists specifically to prevent this scenario - the application never holds the actual secret value in its own files at all.
Core Principles
The pattern that makes Key Vault genuinely secure, rather than just another place to paste a password, depends on Managed Identity - an identity automatically tied to an Azure resource (like a VM) that Azure itself manages, with no credential file for you to create, store, or leak.
+------------------------------------------+| VM with Managed Identity enabled |+------------------------------------------+ | | (Azure AD token, no | credential file needed) v+------------------------------------------+| Azure Key Vault || Checks: does this identity have permission || to read this specific secret? |+------------------------------------------+ | v+------------------------------------------+| Secret value returned to the application || at runtime - never stored in app config |+------------------------------------------+The application code calls the Key Vault SDK, Azure verifies the calling VM's Managed Identity has the correct access policy, and the secret is returned - all without a single credential ever appearing in the application's own files.
Detailed Step-by-Step Practical Lab
- Create a Resource Group and a Key Vault:
az group create --name rg-keyvault-lab-mumbai --location centralindia az keyvault create \ --name kv-lab-rahul-01 \ --resource-group rg-keyvault-lab-mumbai \ --location centralindia- Store a secret in the vault - here, a database connection string:
az keyvault secret set \ --vault-name kv-lab-rahul-01 \ --name "sql-connection-string" \ --value "Server=prod-sql.database.windows.net;Database=orders;..."- Create a VM with a System-Assigned Managed Identity enabled at creation time:
az vm create \ --resource-group rg-keyvault-lab-mumbai \ --name vm-app-lab \ --image Ubuntu2204 \ --size Standard_B1s \ --admin-username azureadmin \ --generate-ssh-keys \ --assign-identityNote
--assign-identitygives the VM its own System-Assigned Managed Identity, a unique identity automatically tied to this specific VM's lifecycle - it's deleted automatically if the VM itself is deleted, with no separate credential to manage.
- Grant that VM's Managed Identity permission to read secrets from the vault:
IDENTITY_ID=$(az vm show \ --resource-group rg-keyvault-lab-mumbai \ --name vm-app-lab \ --query identity.principalId --output tsv) az keyvault set-policy \ --name kv-lab-rahul-01 \ --object-id $IDENTITY_ID \ --secret-permissions get list- SSH into the VM and confirm it can retrieve the secret using its own identity, with no stored credentials anywhere on the VM:
# Get a token for the Key Vault using the VM's own Managed Identitycurl -H "Metadata:true" \ "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://vault.azure.net" \ | jq -r '.access_token' > token.txt # Use that token to retrieve the secretcurl -H "Authorization: Bearer $(cat token.txt)" \ "https://kv-lab-rahul-01.vault.azure.net/secrets/sql-connection-string?api-version=7.4"Note
169.254.169.254is the Azure Instance Metadata Service - a special local address every Azure VM can reach to ask "what identity am I, and can you get me a token for this resource" without any credential file being involved anywhere in that request.
- Clean up:
az group delete --name rg-keyvault-lab-mumbai --yes --no-waitProduction Best Practices & Common Pitfalls
Common MistakeStoring a secret in Key Vault, but then retrieving it once and hardcoding the retrieved value into application config anyway "to save an API call." This defeats the entire purpose - the application should retrieve the secret fresh at startup or runtime, so rotating the secret in Key Vault actually takes effect without a code or config change.
SecurityEnable soft-delete and purge protection on every production Key Vault. Soft-delete means an accidentally deleted secret can be recovered within a retention window rather than being gone instantly and permanently.
- Prefer Managed Identity over service principals with stored credentials wherever the resource type supports it. A service principal still requires a client secret or certificate to be stored somewhere; Managed Identity requires nothing to be stored at all.
- Grant the narrowest secret permissions actually needed. An application that only ever reads secrets should be granted
getandlist, not the ability tosetordeletesecrets it will never need to modify.
Quick Reference & Troubleshooting Commands
| Command | Description |
|---|---|
az keyvault create |
Create a new Key Vault |
az keyvault secret set |
Store a secret in the vault |
az vm create --assign-identity |
Create a VM with a Managed Identity |
az keyvault set-policy |
Grant an identity permission to access the vault |