Key Vault access — permission models, network, soft delete and errors

Why a Key Vault call is refused and how to fix it — Azure RBAC vs legacy access policies, the 2026-02-01 default flip and the February 27, 2027 retirement of older control-plane API versions, data roles, why the creator of a new vault can't read it, the token audience, firewall and trusted services, 429 throttling, soft delete and purge protection name conflicts — each error with cause, check and fix.

markdownreferencev194B6-102Sstage: operatetrust: officialtrust: fieldservice: keyvaultinterface: anyKey Vault 403ForbiddenByRbacCaller is not authorized to perform action on resourcedoes not have secrets get permissionClient address is not authorized and caller is not a trusted serviceKey Vault 401Key Vault 429enableRbacAuthorization default 2026-02-01access policy vs RBACKey Vault Secrets UserKey Vault AdministratorKey Vault Contributoraz keyvault create rbac defaultsoft deletepurge protectionvault name in deleted stateaz keyvault purgeaz keyvault recoverUnknown Policyhttps://vault.azure.net/.default

Created 21 Oct 2026 · Modified 23 Oct 2026 · 1 version

A Key Vault request passes three gates: a valid token for https://vault.azure.net, the vault's network rules, and the vault's permission model. The permission model is either Azure RBAC (role assignments, the default for new vaults) or legacy access policies (set on the vault). A vault uses exactly one: when RBAC is on, access policies are ignored.

The 2026 default flip

  • API version 2026-02-01 and later: enableRbacAuthorization defaults to true. In 2025-05-01 and earlier it defaulted to false. az keyvault create (CLI 2.91) also enables RBAC by default.
  • The default applies to create only. Existing vaults keep their model when updated with a newer API version; vaults with enableRbacAuthorization: null (made with older versions) keep using access policies.
  • So a Bicep or ARM template pinned to an older API version creates an access-policy vault, and the same template moved to 2026-02-01 creates an RBAC vault whose accessPolicies are ignored. Set enableRbacAuthorization explicitly in every template.
  • All Key Vault control-plane API versions before 2026-02-01 retire on February 27, 2027, after which their use is suspended. Move templates and tools now: Azure CLI 2.90.0+, Azure PowerShell 16.3.0+.
  • The creator of an RBAC vault has no data access. Creating it needs control-plane rights only. Reading or writing secrets afterwards needs a data role, for example Key Vault Secrets Officer for yourself. The CLI only adds default permissions for the creator when RBAC is set to false.

Roles (RBAC vaults)

NeedRole
Read secret values (apps)Key Vault Secrets User
Manage secrets (pipelines, people)Key Vault Secrets Officer
Everything in the data planeKey Vault Administrator
Use keys for cryptoKey Vault Crypto User (Crypto Officer to manage)
CertificatesKey Vault Certificates Officer / Certificate User
Read metadata onlyKey Vault Reader
Manage the vault resourceKey Vault Contributor: control plane only

On an access-policy vault, Contributor is enough to grant yourself data access (by writing an access policy). One more reason to use RBAC.

Errors

Status / messageCause → fixCheck
401No Authorization header, an expired token, or a token for another audience. The scope is https://vault.azure.net/.default. (One Microsoft page says vault.keyvault.net; its own examples and the SDK use vault.azure.net.)Decode the token: aud must be https://vault.azure.net
403 Caller is not authorized to perform action on resource. with inner error ForbiddenByRbacRBAC vault, and the caller has no data role at the vault (or above)az role assignment list --assignee <object-id> --scope $(az keyvault show -n <kv> --query id -o tsv) --include-inherited
403 The user, group or application '…' does not have secrets get permission on key vault '…' (field wording)Access-policy vault without a policy for this object ID. Often the app runs as a different identity than the one in the policyaz keyvault show -n <kv> --query "properties.accessPolicies[].objectId" vs the caller's object ID
403 Client address (<ip>) is not authorized and caller is not a trusted serviceThe vault firewall blocks the caller. App Service is not a trusted service: add its outbound IPs or a private endpointaz keyvault network-rule list -n <kv>; az keyvault show -n <kv> --query properties.networkAcls
403 right after adding the policy or rolePropagation: allow several minutes and retry; managed identities in Entra groups can take hoursRetry later
Access policy shows Unknown PolicyThe principal was deleted, or the policy was added with the application object ID instead of the service principal'saz ad sp show --id <id>
429Throttled. Cache secrets in the app, back off exponentially, and spread load across vaults. Read the limits on the Key Vault service limits pageRequest rate in your logs
Vault name conflicts on createA soft-deleted vault with that name still exists. Recover it (az keyvault recover --name <kv>) or, without purge protection, purge it (az keyvault purge --name <kv>)az keyvault list-deleted
Secret name conflicts on setA deleted secret with that name is in the recoverable stateaz keyvault secret list-deleted --vault-name <kv>, then az keyvault secret recover or purge
Purge refusedPurge protection is on: nothing can be purged until the retention period endsaz keyvault show -n <kv> --query properties.enablePurgeProtection

Soft delete and purge protection

Soft delete is on for every new vault and can't be turned off. Retention is 7–90 days (default 90) and is fixed at creation. Purge protection is off by default; once on, deleted vaults and objects can't be purged before retention ends. Plan names accordingly: a vault deleted in a test teardown blocks its name until purged or expired.

When none of these fits

Check the three gates in order: the token's aud and identity, then networkAcls and private endpoints (networking family), then enableRbacAuthorization and the matching role or policy. To switch an access-policy vault to RBAC, az keyvault update -n <kv> --enable-rbac-authorization true needs Microsoft.Authorization/roleAssignments/write and Microsoft.KeyVault/vaults/write. Create every role assignment first (Microsoft's migration order): once RBAC is on, access policies are ignored.

To see who read or changed secrets, send the vault's AuditEvent logs to a workspace with a diagnostic setting: reference/monitor/diagnostic-settings-and-data-collection.md.

Read this document as markdown — the same bytes an agent receives.