Azure Key Vault as a Configuration Provider in .NET
Every .NET application has secrets — database connection strings, API keys, certificates. The question isn't whether you need secret management; it's whether your current approach will survive an audit.
Azure Key Vault integrates directly into the .NET configuration system. Your code reads IConfiguration["ConnectionStrings:Database"] as usual, but the value comes from Key Vault instead of appsettings.json. No code changes needed downstream.
Adding the Configuration Provider
Install the Azure.Extensions.AspNetCore.Configuration.Secrets package and wire it into your host builder:
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddAzureKeyVault(
new Uri("https://my-vault.vault.azure.net/"),
new DefaultAzureCredential());
var app = builder.Build();
That's it. Every secret in the vault is now available through IConfiguration. The provider loads all secrets at startup and caches them in memory.
Secret Naming Conventions
Key Vault doesn't allow colons in secret names, but .NET configuration uses colons as section separators. The convention is to use double hyphens (--) in Key Vault, which the provider translates to colons:
| Key Vault Secret Name | Configuration Key |
|---|---|
ConnectionStrings--Database |
ConnectionStrings:Database |
Smtp--Host |
Smtp:Host |
Smtp--Port |
Smtp:Port |
This means you can bind to options classes seamlessly:
builder.Services.Configure<SmtpOptions>(
builder.Configuration.GetSection("Smtp"));
public class SmtpOptions
{
public string Host { get; set; } = string.Empty;
public int Port { get; set; }
public string ApiKey { get; set; } = string.Empty;
}
The ApiKey value comes from a Key Vault secret named Smtp--ApiKey, but your code never knows the difference.
Filtering Secrets with Prefixes
In shared vaults, you may want to load only secrets relevant to your application. Use a custom key vault manager to filter and transform secret names:
builder.Configuration.AddAzureKeyVault(
new Uri("https://my-vault.vault.azure.net/"),
new DefaultAzureCredential(),
new PrefixKeyVaultSecretManager("MyApp"));
public class PrefixKeyVaultSecretManager : KeyVaultSecretManager
{
private readonly string _prefix;
public PrefixKeyVaultSecretManager(string prefix)
{
_prefix = $"{prefix}--";
}
public override bool Load(SecretProperties properties)
{
return properties.Name.StartsWith(_prefix, StringComparison.OrdinalIgnoreCase);
}
public override string GetKey(KeyVaultSecret secret)
{
return secret.Name[_prefix.Length..]
.Replace("--", ConfigurationPath.KeyDelimiter);
}
}
A secret named MyApp--ConnectionStrings--Database becomes ConnectionStrings:Database in configuration, and secrets without the MyApp-- prefix are ignored entirely.
Reloading Secrets
By default, secrets are loaded once at startup. For long-running applications, you may want periodic reloading:
builder.Configuration.AddAzureKeyVault(
new Uri("https://my-vault.vault.azure.net/"),
new DefaultAzureCredential(),
new AzureKeyVaultConfigurationOptions
{
ReloadInterval = TimeSpan.FromMinutes(5)
});
This polls Key Vault every five minutes and updates the configuration values in place. Combined with IOptionsSnapshot<T>, your services pick up new values on the next scope without a restart.
Be mindful of Key Vault throttling limits. A five-minute interval is reasonable for most applications. Don't set it to seconds.
Local Development
For local development, you don't want to hit Key Vault at all. Use the configuration precedence system — values in appsettings.Development.json or user secrets override Key Vault:
if (builder.Environment.IsProduction())
{
builder.Configuration.AddAzureKeyVault(
new Uri(builder.Configuration["KeyVault:Uri"]!),
new DefaultAzureCredential());
}
Or use dotnet user-secrets to store development values locally. They sit outside your project directory and never end up in source control.
Authentication
DefaultAzureCredential handles authentication across environments:
- Locally: uses your Azure CLI login, Visual Studio credentials, or environment variables.
- In Azure: uses the managed identity assigned to your App Service, Container App, or VM.
No connection strings or client secrets needed in your configuration provider setup. The credential chain tries each method in order until one succeeds.
What Doesn't Belong in Key Vault
Key Vault is for secrets — values that would cause harm if exposed. Don't put every configuration value there:
- Secrets: connection strings, API keys, certificates — yes.
- Feature flags, timeouts, URLs: use Azure App Configuration or
appsettings.json. - Large values: Key Vault secrets are limited to 25 KB. For larger data, store it in Blob Storage and put the SAS token or reference in Key Vault.
Key Vault as a configuration provider is one of the cleanest patterns in the Azure/.NET ecosystem. It requires minimal code, respects the standard configuration hierarchy, and eliminates an entire class of security risks.