This article looks at setting up an ASP.NET Core application to use Azure Key Vault. When deployed to Azure, it works like in the Azure documentation but when working on development PCs, some changes are required for a smooth developer experience.
Code: https://github.com/damienbod/UsingAzureKeyVaultInDevelopment
I develop using Visual Studio and manage multiple accounts and test environments. However, I frequently encounter access errors when using DefaultAzureCredentials. These errors typically occur because the account and tenant do not match the filter set in Visual Studio, or the user lacks access to the tenant. This issue arises often:

The problem can be resolved by using an application client secret to access the Azure Key Vault, implemented with the ChainedTokenCredential. The access client can be specified in the project’s user secrets, allowing it to function independently of the user account and the last filter used in Visual Studio. To set this up, a new Azure App registration was created, and a client secret was added. This client secret is then included in the dotnet user secrets for the project.

A Role assignment was added to the Azure Key Vault for the application service principal, and the necessary access role was configured. With the correct configuration in the user secrets on the development PC, the application can access the Azure Key Vault. This setup eliminates the need for Azure RBAC changes for each developer.

Setup local development credentials
The following Nuget packages can be used to integrate a Key Vault client in an ASP.NET Core application. Depending on how the client is setup, or what data is used from the Key Vault, different packages can be used.
- Azure.Extensions.AspNetCore.Configuration.Secrets
- Azure.Identity
- Azure.Security.KeyVault.Certificates
- Azure.Security.KeyVault.Secrets
A ChainedTokenCredential is used to access the Key Vault, preventing the access issues associated with DefaultAzureCredential. In local development, a client credential is used via a secret, which can be stored in the dotnet user secrets. When a new developer joins the team, these user secrets can be shared, eliminating the need to modify Azure Key Vault RBAC settings for each new developer. This setup is ideal for development, as it avoids problems caused by incorrect tenants or user accounts in Visual Studio. For production or other deployments, a system-assigned managed identity is used.
using Azure.Identity;
namespace DevelopmentAspNetCoreKeyVault;
public static class AppAccessCredentials
{
public static ChainedTokenCredential GetChainedTokenCredentials(IConfiguration configuration, bool isDevelopment)
{
if (!isDevelopment)
{
// Use a system assigned managed identity on production deployments
return new ChainedTokenCredential(new ManagedIdentityCredential());
}
else // dev env
{
var tenantId = configuration["EntraId:TenantId"];
var clientId = configuration.GetValue<string>("EntraId:ClientId");
var clientSecret = configuration.GetValue<string>("EntraId:ClientSecret");
var options = new TokenCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};
// https://docs.microsoft.com/dotnet/api/azure.identity.clientsecretcredential
var devClientSecretCredential = new ClientSecretCredential(
tenantId, clientId, clientSecret, options);
var chainedTokenCredential = new ChainedTokenCredential(devClientSecretCredential);
return chainedTokenCredential;
}
}
}
The user secrets would have something like this:
{
"EntraId": {
// aspnetcore-keyvault-development-access
"TenantId": "--tenant_id--",
"ClientId": "--client_id--",
"ClientSecret": "--secret--"
}
}
Using Key Vault directly in the application
The secret from the Azure Key Vault can be used directly in the code by using the SecretClient class from Azure.Identity. The AppAccessCredentials is used to return the chained credentials and the application is authenticated if the service principal from the App registration has the correct RBAC.
// Azure SDK direct
var client = new SecretClient(new Uri(_configuration["AzureKeyVaultEndpoint"]!),
AppAccessCredentials.GetChainedTokenCredentials(_configuration,
_hostEnvironment.IsDevelopment()));
var secret = await client.GetSecretAsync("demosecret");
DemoSecret = secret!.Value.Value;
Using Key Vault as a configuration
The AddAzureKeyVault method can be used to use the Azure Key as a further configuration option. I like this as all configuration is abstracted with the IConfiguration interface in the application. The AddAzureKeyVault takes the chained credential as a param.
var keyVault = builder.Configuration["AzureKeyVaultEndpoint"];
if(!string.IsNullOrEmpty(keyVault))
{
builder.Configuration.AddAzureKeyVault(
new Uri($"{builder.Configuration["AzureKeyVaultEndpoint"]}"),
AppAccessCredentials.GetChainedTokenCredentials(builder.Configuration,
builder.Environment.IsDevelopment()));
}
The secret can be read anywhere in the code using the IConfiguration interface. This can be used in different ways and provides type safe ways of using the properties.
// ASP.NET Core configuration
// From from key vault using ASP.NET Core configuration integration
// Or from user secrets if offline, or fast startup is required
DemoSecretConfig = _configuration["demosecret"];
Using user secrets for local development
Sometimes, you need to work offline or frequently restart the application. Constantly connecting to Azure Key Vault can slow down development. In such cases, it’s often more efficient to use dotnet user secrets instead of Azure Key Vault.
Note
This is a good and simple approach for developing applications which use Azure Key Vault. You can use a local key management system or whatever local developers use. The client secret should not be used in production deployments as the secret expires and there are better ways to secure the access for the application to Key Vault. System assigned managed identity is the best way to implement application access in Azure in production environments.
Links
https://learn.microsoft.com/en-us/aspnet/core/security/key-vault-configuration
https://docs.microsoft.com/en-us/azure/key-vault/key-vault-developers-guide
https://stackoverflow.com/questions/40025598/azure-key-vault-access-denied
https://cmatskas.com/securing-asp-net-core-application-settings-using-azure-key-vault/
https://github.com/jayendranarumugam/DemoSecrets/tree/master/DemoSecrets
https://docs.microsoft.com/en-us/cli/azure/install-azure-cli-windows?view=azure-cli-latest
https://anthonysimmon.com/defaultazurecredential-local-development-optimization/