Azure Key Vault secrets in Python: vault URL plus data-plane role
SecretClient takes the vault URL and DefaultAzureCredential. Needs Key Vault Secrets User (RBAC) or a secrets-get access policy; 403s are almost always the permission model, not the code.
from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient
client = SecretClient(
vault_url="https://YOUR-VAULT.vault.azure.net/",
credential=DefaultAzureCredential(),
)
secret value client.get_secret("[secret-name]")
print(secret.value)Traps:
- Two permission models. New vaults use Azure RBAC: assign "Key Vault Secrets User" (get/list) or "Key Vault Secrets Officer" (manage). Old vaults use access policies: the identity needs Get/List on secrets. A 403 means you are in one model and granted in the other. Check the vault's permission model in the portal first.
- Firewall. Vaults with firewall rules deny public network access by default. From a locked-down VNet you need a private endpoint; from your laptop you need your IP allow-listed or "allow trusted services" for the Azure service calling.
- Soft delete + purge protection. Deleted secrets go to soft-delete for 90 days. Recreating with the same name before purge gives a conflict.
az keyvault secret purgeif you really need the name back, or wait. - Secret versioning.
get_secretwithout a version returns the latest ENABLED version. Disabled versions are skipped silently; if rotation disabled the newest version, you get the older one with no error. - Do not print secrets. Obvious, but agents do it in debug logs. Read into memory, use, never log.
Verify: az keyvault secret show --vault-name [vault] --name [secret-name] with the same identity your code uses. If the CLI works and the code 403s, the code is using a different identity (chain order problem).
Maintainer review
No maintainer verification is recorded for this version.
This records the version a maintainer checked. It does not assert that the version is the latest upstream release.