App Service Key Vault references sound like a niche Azure problem until a production app boots with literal @Microsoft.KeyVault(...) strings, stale secrets or a bare “Forbidden.” This checklist covers Azure App Service and Azure Functions: reference syntax, managed identity selection, Key Vault data-plane permissions, firewall and private endpoint behavior, deployment slots, and refresh timing.
Admin quick take
When Key Vault references fail, check identity, data access and network path, in that order.
- Identity: App Service uses the system-assigned identity by default, unless
keyVaultReferenceIdentitypoints to a user-assigned identity. - Permission: the identity needs secret read access: Key Vault Secrets User with Azure RBAC, or Get on secrets with access policies.
- Network: for restricted vaults, don’t rely on public outbound IPs; route through the virtual network the vault allows.
- Refresh: unversioned references pick up new versions, but values can be cached for up to 24 hours unless a restart or refresh forces a refetch.
How App Service Key Vault references work
An app setting or connection string keeps its normal name, but its value points to a Key Vault secret. Your code reads it like any environment variable and the platform resolves the secret, which means fewer secrets in configuration, cleaner rotation and a better audit trail. The feature is unforgiving, though: if any layer below is wrong, the setting won’t resolve.
| Layer | What must be true | Common symptom |
|---|---|---|
| Reference syntax | A valid reference pointing to the right secret. | Setting stays unresolved or points to the wrong secret. |
| Managed identity | The expected identity exists on the app or slot. | Access denied even though a different identity has permission. |
| Key Vault authorization | Data-plane secret read access. | 403 Forbidden or failed SecretGet events. |
| Network | An allowed public, service endpoint or private endpoint path. | 403 or timeouts after firewall or private endpoint changes. |
| Refresh behavior | Rotation expectations match App Service caching. | Secret updated, app still sees the old value. |
1. Confirm the reference syntax
Start with the typo check. A reference can use a full secret URI, which is easiest to validate:
@Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret)
Or the vault/name format:
@Microsoft.KeyVault(VaultName=myvault;SecretName=mysecret)
Including a secret version pins the app to it until you edit the reference. That suits controlled rollouts, but it isn’t automatic rotation. Omit the version if rotation should flow through on its own.
2. Verify the managed identity in use
Key Vault references use the system-assigned identity by default, which suits most apps. Admins commonly get caught in three scenarios:
- Secrets are needed during creation, before a system-assigned identity exists. A user-assigned identity can be prepared in advance.
- Several identities exist, and the one with Key Vault access isn’t the one used for reference resolution.
- Deployment slots are involved; identity configuration is slot-specific.
For a user-assigned identity, set keyVaultReferenceIdentity to its resource ID; set it to SystemAssigned to return to the default. If the app moved tenants or subscriptions, recheck identity object IDs and role assignments.
3. Grant data-plane access, not just Contributor
Key Vault separates the control plane from the data plane. Permission to manage the vault doesn’t let the app read a secret, and “I can see the vault in the portal” isn’t a permissions test.
- Identify the exact managed identity object used by the app or slot.
- Check whether the vault uses Azure RBAC or access policies.
- Grant Key Vault Secrets User (RBAC) or Get on secrets (access policy) at the narrowest practical scope.
- Allow time for role assignment propagation.
- Verify with Key Vault diagnostic logs or a controlled restart.
4. Check the firewall, VNet integration and private DNS
Microsoft’s guidance is clear: for network-restricted vaults, don’t depend on the app’s public outbound IPs, because the request’s origin IP can differ. Configure the vault to accept traffic from the virtual network the app uses, then check these together:
- VNet integration is connected to the expected subnet.
- Linux apps reaching private endpoints may need all traffic routed through the VNet with
vnetRouteAllEnabled(Flex Consumption function apps route automatically). - Private endpoint DNS resolves correctly from the app’s path, not just from your laptop.
az webapp config set \
--resource-group <resource-group> \
--subscription <subscription> \
--name <app-name> \
--generic-configurations '{"vnetRouteAllEnabled": true}'
One documented quirk: even with the private path working, Key Vault logs may show a failed 403 SecretGet from the public outbound IP followed by a successful one from the private IP. Microsoft says that’s by design, so don’t chase the first 403 if the private request succeeds.
5. Treat deployment slots separately
| Slot item | Recommended check | Why it matters |
|---|---|---|
| Managed identity | Confirm the slot has the expected identity. | Slots can behave differently. |
| Setting stickiness | Mark environment-specific references as slot settings. | Stops swaps pointing at the wrong vault or secret. |
| Vault access | Grant each slot identity access to its matching vault. | Production working doesn’t prove staging is configured. |
| Network path | Validate VNet integration and DNS per environment. | Private networking issues often hide until slot testing. |
| Swap | Test references after a swap, not only before. | Catches stickiness mistakes. |
6. Understand refresh timing before calling it broken
Without a version, App Service uses the latest secret version, but Microsoft documents that it caches values and refetches every 24 hours. A configuration change that restarts the app triggers an immediate refetch, and a management API endpoint can force a refresh. “I rotated the secret” and “the app is using the new value” aren’t the same sentence: plan a refresh for urgent rotations and document the window for routine ones.
7. Use logs to separate auth, network and missing-secret failures
Pair the reference status in App Service configuration with Key Vault diagnostic logs:
- 403 Forbidden: usually authorization, the wrong identity or a network restriction.
- Secret not found: a typo, a deleted or disabled secret, or a pinned version that no longer exists.
- Still the old value: the cache window, a pinned version, no restart, or the app reading a different setting.
- Works in one slot only: slot identity, slot setting or vault mismatch.
Guardrails that prevent repeat incidents
- One vault per app per environment where practical, in line with Microsoft’s Key Vault RBAC guidance.
- Managed identity over stored credentials.
- Document the expected identity and vault in IaC outputs or the runbook.
- Make environment-specific references slot settings.
- Monitor Key Vault diagnostics; secret read failures are operational signals.
- Pin secret versions only when you mean it.
App Service Key Vault references are simple; the surrounding system isn’t. When identity, RBAC, networking, slots and refresh timing agree, secret management becomes boring in the best way. Related: Azure API Management managed identity troubleshooting, Azure diagnostic settings policy and Azure Resource Locks for protecting production vaults.
Last reviewed: October 2026
Sources
- Use Key Vault references as app settings in Azure App Service (Microsoft Learn)
- Managed identities in Azure App Service (Microsoft Learn)
- Azure Key Vault RBAC guide (Microsoft Learn)
- Configure network security for Azure Key Vault (Microsoft Learn)
- Access Azure Key Vault behind a firewall (Microsoft Learn)
Discover more from Cloud Osprey
Subscribe to get the latest posts sent to your email.