The goal
Passwords and connection strings are sitting in config files or scripts. Key Vault gives them one protected home, with access control and an audit trail. This post covers the everyday tasks: create a vault, store a secret, let an app read it and recover it if someone deletes it.
Step 1: create the vault
Vault names are globally unique, 3-24 characters, using letters, numbers and hyphens.
az group create --name rg-kv-demo --location centralindia
az keyvault create \
--name kv-ops-demo-2611 \
--resource-group rg-kv-demo \
--location centralindia \
--enable-rbac-authorization true
RBAC mode means access is managed with normal Azure role assignments. Older vaults may still use access policies; check yours with:
az keyvault show --name kv-ops-demo-2611 --query properties.enableRbacAuthorization
Step 2: give yourself access
Creating a vault doesn't let you read its contents. Control-plane rights (managing the vault) and data-plane rights (reading secrets) are separate.
VAULT_ID=$(az keyvault show --name kv-ops-demo-2611 --query id -o tsv)
az role assignment create \
--role "Key Vault Secrets Officer" \
--assignee "you@contoso.com" \
--scope "$VAULT_ID"
| Role | Can do |
|---|---|
| Key Vault Administrator | All data-plane actions on secrets, keys and certificates |
| Key Vault Secrets Officer | Manage secrets, but not access rules |
| Key Vault Secrets User | Read secret values only. Use this for apps |
| Key Vault Reader | See metadata, but not secret values |
Allow a few minutes for a new role assignment to apply.
Step 3: store and read a secret
az keyvault secret set --vault-name kv-ops-demo-2611 --name app-db-password --file ./db-password.txt
az keyvault secret show --vault-name kv-ops-demo-2611 --name app-db-password --query value -o tsv
az keyvault secret list --vault-name kv-ops-demo-2611 --query "[].name" -o tsv
Tip
--valuealso works, but it leaves the secret in your shell history. Using--fileavoids that. Delete the file afterwards.
Setting a secret with an existing name creates a new version. Old versions stay available:
az keyvault secret list-versions --vault-name kv-ops-demo-2611 --name app-db-password -o table
Set an expiry date so you can track rotation:
az keyvault secret set-attributes \
--vault-name kv-ops-demo-2611 --name app-db-password \
--expires 2027-05-01T00:00:00Z
Expiry is a reminder, not a lock. Key Vault doesn't remove or rotate an expired secret, and a get call can still return it. Set up an alert on the date and rotate before it.
Step 4: let an application read it
Give the app's managed identity the reader role, on the vault or on one secret:
PRINCIPAL_ID=$(az webapp identity show --name app-ops --resource-group rg-app --query principalId -o tsv)
az role assignment create \
--role "Key Vault Secrets User" \
--assignee-object-id "$PRINCIPAL_ID" \
--assignee-principal-type ServicePrincipal \
--scope "$VAULT_ID"
Reading it from Python, with no password in the code:
# pip install azure-identity azure-keyvault-secrets
from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient
client = SecretClient(
vault_url="https://kv-ops-demo-2611.vault.azure.net",
credential=DefaultAzureCredential(),
)
password = client.get_secret("app-db-password").value
DefaultAzureCredential uses the managed identity in Azure and your az login session on a laptop, so the same code works in both.
When access fails
| Message | Cause | Fix |
|---|---|---|
Caller is not authorized to perform action / ForbiddenByRbac | No data-plane role | Add a Key Vault role at the vault scope |
Forbidden with ForbiddenByFirewall | The vault firewall blocks your IP | Allow the IP or use a private endpoint |
SecretNotFound | Wrong name, or the secret was deleted | Check the name and list deleted secrets |
Operation get is not allowed on a disabled secret | The secret is disabled | Re-enable it with set-attributes --enabled true |
VaultAlreadyExists / ConflictError on create | Name is taken, or in a soft-deleted vault | Pick another name or recover the vault |
More detail is in Key Vault access denied.
Recover a deleted secret
Soft delete keeps deleted secrets for the retention period set on the vault.
az keyvault secret delete --vault-name kv-ops-demo-2611 --name app-db-password
az keyvault secret list-deleted --vault-name kv-ops-demo-2611 -o table
az keyvault secret recover --vault-name kv-ops-demo-2611 --name app-db-password
Caution
az keyvault secret purgeremoves a deleted secret permanently. There's no way back. For production vaults, turn on purge protection withaz keyvault update --name <vault> --enable-purge-protection true. It can't be turned off afterwards.
Prevent it next time
- Grant
Key Vault Secrets Userto apps, not Officer or Administrator. - Keep separate vaults for production and non-production, so a dev identity can't reach production secrets.
- Send vault diagnostic logs to Log Analytics, so you can see who read what.
- For app settings, use Key Vault references rather than loading secrets by hand.
- When you're ready for vault layout decisions, read the Key Vault design guide.