Keywords: Azure KeyVault | DefaultAzureCredential | Environment Variables
Abstract: This technical article provides an in-depth analysis of DefaultAzureCredential authentication failures when integrating Azure KeyVault with ASP.NET Core applications deployed on classic Azure virtual machines. Focusing on the root causes of Azure.Identity.CredentialUnavailableException, the article details the critical role of environment variable configuration, including proper setup of AZURE_CLIENT_ID, AZURE_TENANT_ID, and AZURE_CLIENT_SECRET. With comprehensive code examples and configuration guidelines, it offers a complete technical pathway from problem diagnosis to solution implementation for secure secret management in legacy environments without managed identity support.
Problem Context and Exception Analysis
When deploying ASP.NET Core applications targeting .NET Framework to classic Azure virtual machines, developers frequently encounter authentication failures with Azure KeyVault integration. Classic VMs typically lack managed identity support, preventing DefaultAzureCredential from automatically obtaining access tokens. The exception log reveals crucial information:
Azure.Identity.CredentialUnavailableException: DefaultAzureCredential failed to retrieve a token from the included credentials
EnvironmentCredential authentication unavailable. Environment variables are not fully configured
ManagedIdentityCredential authentication unavailable, the requested identity has not been assigned to this resource.
This exception clearly indicates failures in two authentication pathways: EnvironmentCredential is unavailable due to incomplete variable configuration, and ManagedIdentityCredential is unavailable because no identity is assigned to the resource. In classic VM environments, without managed identity support, we must rely on environment variable configuration for authentication credentials.
Core Requirements for Environment Variable Configuration
According to Azure SDK documentation and best practices, the following three environment variables must be properly configured for EnvironmentCredential to function correctly:
AZURE_CLIENT_ID: The application ID of the service principalAZURE_TENANT_ID: The ID of the Azure Active Directory tenant to which the service principal belongsAZURE_CLIENT_SECRET: One of the client secrets for the service principal
These variables provide DefaultAzureCredential with all necessary information for authentication via service principal. In classic VM environments, this represents the most reliable and recommended authentication approach.
Configuration Implementation Steps
First, create a service principal in the Azure portal and assign appropriate KeyVault access permissions. Then, set the system environment variables on the target virtual machine:
// Setting environment variables via PowerShell (requires administrator privileges)
[System.Environment]::SetEnvironmentVariable("AZURE_CLIENT_ID", "your-client-id", "Machine")
[System.Environment]::SetEnvironmentVariable("AZURE_TENANT_ID", "your-tenant-id", "Machine")
[System.Environment]::SetEnvironmentVariable("AZURE_CLIENT_SECRET", "your-client-secret", "Machine")
After configuration, restart the application or IIS for the environment variables to take effect. Verify that the environment variables are properly loaded:
// Verifying environment variables in C# code
var clientId = Environment.GetEnvironmentVariable("AZURE_CLIENT_ID");
var tenantId = Environment.GetEnvironmentVariable("AZURE_TENANT_ID");
var clientSecret = Environment.GetEnvironmentVariable("AZURE_CLIENT_SECRET");
if (string.IsNullOrEmpty(clientId) || string.IsNullOrEmpty(tenantId) || string.IsNullOrEmpty(clientSecret))
{
throw new InvalidOperationException("Azure environment variables are not properly configured");
}
Application Configuration Adjustments
In the Startup configuration, ensure proper usage of DefaultAzureCredential:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((context, config) =>
{
var vaultName = ConfigurationManager.AppSettings["VaultName"];
if (!string.IsNullOrEmpty(vaultName))
{
// Using DefaultAzureCredential, which automatically detects environment variables
var credential = new DefaultAzureCredential();
config.AddAzureKeyVault(
new Uri($"https://{vaultName}.vault.azure.net/"),
credential,
new DefaultKeyVaultSecretManager());
}
})
.UseStartup<Startup>();
This approach aligns better with modern Azure SDK design patterns compared to using AzureServiceTokenProvider and handles various authentication scenarios more effectively.
Web.config Configuration Considerations
For applications still using web.config, ensure configuration builders properly reference KeyVault:
<configBuilders>
<builders>
<add name="AzureKeyVault"
vaultName="YourVaultName"
type="Microsoft.Configuration.ConfigurationBuilders.AzureKeyVaultConfigBuilder, Microsoft.Configuration.ConfigurationBuilders.Azure"
vaultUri="https://YourVaultName.vault.azure.net" />
</builders>
</configBuilders>
<connectionStrings configBuilders="AzureKeyVault">
<add name="ConnectionString" connectionString="" providerName="System.Data.SqlClient"/>
</connectionStrings>
Configuration builders automatically use credentials from environment variables to access KeyVault without additional code.
Supplementary Solutions and Best Practices
Beyond environment variable configuration, several supplementary solutions merit consideration. When using Visual Studio for development, ensure Azure service authentication is properly configured. In Visual Studio, navigate to "Tools > Options > Azure Service Authentication > Account Selection," check and re-enter credentials if necessary. This can resolve authentication issues in local development environments.
For production environments, the following security best practices are recommended:
- Regularly rotate client secrets to minimize security risks
- Use Azure KeyVault to store and manage the client secrets themselves
- Apply the principle of least privilege when assigning permissions to service principals
- Monitor and audit KeyVault access logs
By correctly configuring environment variables and adhering to these best practices, secure and reliable KeyVault integration can be achieved even in classic Azure virtual machine environments, ensuring proper protection of application secrets.