Use Azure Key Vault With Django
Load Django secrets from Azure Key Vault: use Key Vault references in App Service and Container Apps, read secrets with azure-identity and managed identities, mount them on AKS with the Secrets Store CSI driver, and rotate values without redeploying code.
Problem statement
Your Django app runs on Azure, and secrets currently live in App Service application settings or Container Apps secrets in plain form, copied between environments by hand. Azure Key Vault centralizes them with access policies or RBAC, versioning, and audit logs. Each Azure hosting option can pull from Key Vault in its own way, and with managed identities no credentials are needed to reach the vault itself.
- Create a Key Vault with RBAC authorization and add secrets (
django-secret-key,database-url). - Enable a managed identity on the app and grant it the Key Vault Secrets User role on the vault.
- App Service: set an app setting to
@Microsoft.KeyVault(SecretUri=https://shop-kv.vault.azure.net/secrets/django-secret-key/). - Container Apps: define a secret with a Key Vault reference and map it to an environment variable.
- AKS: mount secrets with the Secrets Store CSI driver and workload identity, or read them in code with
azure-identity.
Step-by-step solution
1. Create the vault and secrets
az keyvault create -g shop-prod -n shop-kv --location westeurope --enable-rbac-authorization true
az keyvault secret set --vault-name shop-kv -n django-secret-key \
--value "$(python -c 'import secrets; print(secrets.token_urlsafe(50))')"
az keyvault secret set --vault-name shop-kv -n database-url --value "postgres://..."
Secret names allow letters, digits, and hyphens; map them to Django's underscore names in the platform configuration.
2. Grant the app's identity access
az webapp identity assign -g shop-prod -n shop-web
PRINCIPAL=$(az webapp identity show -g shop-prod -n shop-web --query principalId -o tsv)
az role assignment create --assignee "$PRINCIPAL" --role "Key Vault Secrets User" \
--scope "$(az keyvault show -n shop-kv --query id -o tsv)"
With RBAC, roles can be scoped to the whole vault or a single secret.
3. App Service references
In the app's configuration, set:
SECRET_KEY = @Microsoft.KeyVault(SecretUri=https://shop-kv.vault.azure.net/secrets/django-secret-key/)
DATABASE_URL = @Microsoft.KeyVault(VaultName=shop-kv;SecretName=database-url)
App Service resolves these with the managed identity and exposes the values as environment variables. Without a version in the URI, it picks up new versions periodically and on restart. The Configuration blade shows a green check when a reference resolves.
4. Container Apps
az containerapp secret set -g shop-prod -n shop-web \
--secrets "django-secret-key=keyvaultref:https://shop-kv.vault.azure.net/secrets/django-secret-key,identityref:system"
az containerapp update -g shop-prod -n shop-web \
--set-env-vars "SECRET_KEY=secretref:django-secret-key"
New revisions read the current secret value; restart or create a revision after rotating.
5. AKS and VMs
On AKS, a SecretProviderClass with workload identity mounts secrets as files and can sync them into a Kubernetes Secret for environment variables. On VMs or anywhere else, read secrets in settings:
from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient
_kv = SecretClient(vault_url=os.environ["KEY_VAULT_URL"], credential=DefaultAzureCredential())
SECRET_KEY = os.environ.get("SECRET_KEY") or _kv.get_secret("django-secret-key").value
DefaultAzureCredential uses the managed identity in Azure and your az login session locally.
Explanation
Key Vault stores secrets as versioned objects protected by Azure RBAC and logged through diagnostic settings. Azure's managed hosting services understand Key Vault references and resolve them using the app's managed identity, so Django receives plain environment variables. Where references are not available, the azure-identity library obtains tokens from the same managed identity, keeping credentials out of configuration entirely.
Edge cases / notes
- Network restrictions. If the vault uses private endpoints or firewall rules, the app must reach it through VNet integration, or references fail to resolve.
- Soft delete. Deleted secrets are recoverable for a retention period; reusing a name may require purging first.
- Caching. Fetch secrets once at startup; per-request vault calls add latency and can hit throttling limits.
Next steps
- Host with Deploy Django on Azure App Service.
- Or with Deploy Django on Azure Container Apps.
- Kubernetes on Azure: Deploy Django on AKS.
FAQ
Do I need code changes to use Key Vault on App Service?
No. Key Vault references resolve to environment variables automatically.
How does the app authenticate to Key Vault?
With a managed identity granted the Key Vault Secrets User role.
Why does my reference show an error in the portal?
Usually the identity lacks access, the secret name is wrong, or network rules block the vault.
Do running apps see a new secret version immediately?
Not always. Restart the app or create a new revision to be sure it reads the new value.