Skip to main content

Managing Secrets with Azure Key Vault

Learn to store secrets in Azure Key Vault and retrieve them using Managed Identity so application code never contains a hardcoded credential.

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.

◈ DIAGRAM
+------------------------------------------+
| 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

  1. Create a Resource Group and a Key Vault:
Bash
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
  1. Store a secret in the vault - here, a database connection string:
Bash
az keyvault secret set \
--vault-name kv-lab-rahul-01 \
--name "sql-connection-string" \
--value "Server=prod-sql.database.windows.net;Database=orders;..."
  1. Create a VM with a System-Assigned Managed Identity enabled at creation time:
Bash
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-identity
Note

--assign-identity gives 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.

  1. Grant that VM's Managed Identity permission to read secrets from the vault:
Bash
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
  1. SSH into the VM and confirm it can retrieve the secret using its own identity, with no stored credentials anywhere on the VM:
Bash
# Get a token for the Key Vault using the VM's own Managed Identity
curl -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 secret
curl -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.254 is 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.

  1. Clean up:
Bash
az group delete --name rg-keyvault-lab-mumbai --yes --no-wait

Production Best Practices & Common Pitfalls

Common Mistake

Storing 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.

Security

Enable 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 get and list, not the ability to set or delete secrets 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

Explore More in Azure Storage Solutions

All 6 Topics

Frequently Asked Questions

Is Managing Secrets with Azure Key Vault free to learn on DevOps Network?

Yes - this topic, like everything on DevOps Network, is 100% free with no paywall or sign-up gate.

What does the Managing Secrets with Azure Key Vault topic cover?

Learn to store secrets in Azure Key Vault and retrieve them using Managed Identity so application code never contains a hardcoded credential.