Key Vault References in App Config

Overview

Azure App Service, Azure Functions, and Azure App Configuration support Key Vault references — a way to use Key Vault secrets in application settings without exposing secret values in configuration. The platform resolves the reference at runtime using managed identity.


How Key Vault References Work

Instead of storing a secret value directly in App Settings, you store a reference:

@Microsoft.KeyVault(SecretUri=https://my-vault.vault.azure.net/secrets/DbPassword/)

At runtime, the platform:

  1. Detects the @Microsoft.KeyVault(...) syntax.
  2. Authenticates to Key Vault using the app's managed identity.
  3. Resolves the secret value and injects it into the environment variable.

App Service Configuration

Azure Portal

In App Service > Configuration > Application Settings, set the value to:

@Microsoft.KeyVault(SecretUri=https://my-vault.vault.azure.net/secrets/DbPassword/)

Azure CLI

az webapp config appsettings set \
  --name my-app \
  --resource-group my-rg \
  --settings "DbPassword=@Microsoft.KeyVault(SecretUri=https://my-vault.vault.azure.net/secrets/DbPassword/)"

With Specific Version

@Microsoft.KeyVault(SecretUri=https://my-vault.vault.azure.net/secrets/DbPassword/abc123def456)

Vault Name Shorthand

@Microsoft.KeyVault(VaultName=my-vault;SecretName=DbPassword)

Azure Functions Configuration

Key Vault references work identically in Azure Functions app settings:

az functionapp config appsettings set \
  --name my-func \
  --resource-group my-rg \
  --settings "ServiceBusConnection=@Microsoft.KeyVault(VaultName=my-vault;SecretName=ServiceBusConnStr)"

In function.json Bindings

Function bindings that reference app settings automatically resolve Key Vault references:

{
  "bindings": [
    {
      "type": "serviceBusTrigger",
      "connection": "ServiceBusConnection",
      "queueName": "orders"
    }
  ]
}

The ServiceBusConnection app setting can be a Key Vault reference — the runtime resolves it transparently.


Prerequisites

1. Enable Managed Identity

az webapp identity assign --name my-app --resource-group my-rg

2. Grant Key Vault Access

PRINCIPAL_ID=$(az webapp identity show --name my-app --resource-group my-rg --query principalId -o tsv)

az role assignment create \
  --role "Key Vault Secrets User" \
  --assignee $PRINCIPAL_ID \
  --scope /subscriptions/{sub}/resourceGroups/my-rg/providers/Microsoft.KeyVault/vaults/my-vault

3. Verify Resolution

In the Azure Portal, navigate to App Service > Configuration. Successfully resolved references show a green checkmark. Failed references show a red X with an error message.


Azure App Configuration Integration

Azure App Configuration can store Key Vault references as configuration values, providing a centralized config store that delegates secrets to Key Vault.

Create a Key Vault Reference in App Configuration

az appconfig kv set-keyvault \
  --name my-appconfig \
  --key "Settings:DbPassword" \
  --secret-identifier "https://my-vault.vault.azure.net/secrets/DbPassword"

.NET Integration

builder.Configuration.AddAzureAppConfiguration(options =>
{
    options.Connect(new Uri("https://my-appconfig.azconfig.io"), new DefaultAzureCredential())
           .ConfigureKeyVault(kv =>
           {
               kv.SetCredential(new DefaultAzureCredential());
           });
});

Slot-Specific References

Use deployment slot settings to point different slots to different vaults:

# Production slot
az webapp config appsettings set \
  --name my-app --resource-group my-rg \
  --slot-settings "DbPassword=@Microsoft.KeyVault(VaultName=prod-vault;SecretName=DbPassword)"

# Staging slot
az webapp config appsettings set \
  --name my-app --resource-group my-rg --slot staging \
  --slot-settings "DbPassword=@Microsoft.KeyVault(VaultName=staging-vault;SecretName=DbPassword)"

Troubleshooting

SymptomCauseFix
Red X in portalIdentity lacks accessAssign Key Vault Secrets User role
SecretNotFoundWrong secret name or vaultVerify the SecretUri
Reference not resolvedMissing @Microsoft.KeyVault prefixCheck syntax exactly
Stale value after rotationCached referenceRestart app or wait for refresh (up to 24h)

Force Refresh

Key Vault references are cached. To pick up a new secret version:

  • Restart the app for immediate refresh.
  • Without version pinning, the platform checks for updates periodically (every 24 hours).
  • With App Configuration, use dynamic refresh with sentinel keys.

Bicep/ARM Template

resource webApp 'Microsoft.Web/sites@2022-09-01' = {
  name: 'my-app'
  location: location
  identity: { type: 'SystemAssigned' }
  properties: {
    siteConfig: {
      appSettings: [
        {
          name: 'DbPassword'
          value: '@Microsoft.KeyVault(VaultName=${keyVaultName};SecretName=DbPassword)'
        }
      ]
    }
  }
}

Best Practices

  1. Use Key Vault references instead of storing secrets directly in app settings.
  2. Omit the version in the reference URI to always get the latest secret.
  3. Use managed identity — never store Key Vault credentials in app settings.
  4. Combine with App Configuration for centralized config management with secret delegation.
  5. Use slot-specific settings to isolate secrets per environment.
  6. Monitor resolution status in the Azure Portal configuration blade.
  7. Plan for cache refresh — restart apps after secret rotation if immediate pickup is needed.

Summary

Key Vault references let you keep secrets in Key Vault while referencing them from App Service, Functions, and App Configuration settings. The platform resolves them at runtime using managed identity, providing a zero-secret-in-config pattern that works across all Azure compute services.