Written by: Ismaël Diakité
Date Published: 23 December 2023
Integrating Azure Key Vault with .NET Applications for Secure Configuration Management
Overview
In the realm of modern software development, securing application secrets is paramount. Azure Key Vault provides a robust solution for securely storing and managing these secrets. In this tutorial, we'll explore how to integrate Azure Key Vault with a .NET application to achieve two key objectives:
- Loading Secrets into
appsettings.json
Before Application Startup: Streamlining the process of securely injecting configuration settings. - Pulling All Secrets from Azure Key Vault: Providing a method to retrieve all stored secrets efficiently.
Prerequisites
- Azure Subscription
- Azure Key Vault resource
- .NET 8.0 SDK
- Visual Studio or VS Code
Step 1: Setting up the .NET Project
Create a new .NET console application with the necessary package references for Azure Key Vault, Azure Identity, and Microsoft Extensions Configuration.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<!-- ...Other configuration... -->
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.Extensions.AspNetCore.Configuration.Secrets" Version="1.3.0" />
<PackageReference Include="Azure.Identity" Version="1.10.4" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
Step 2: Configuring appsettings.json
Include the Key Vault endpoint and placeholders for secrets in your appsettings.json
.
{
"AppSecrets": {
"SecretKey1": "",
"SecretKey2": "",
"SecretKey3": "",
// ...other secrets...
},
"SpnConfiguration": {
"TenantId": "",
"ClientId": "",
"ClientSecret": ""
},
"KeyVaultEndpoint": "https://yourkeyvaultname.vault.azure.net/"
}
Step 3: Implementing the secrets retrieval logic
In your Program.cs
, implement the logic to authenticate with Azure Key Vault using a service principal and retrieve the secrets.
using Azure.Identity;
using Azure.Security.KeyVault.Secrets;
using Microsoft.Extensions.Configuration;
namespace PullSecretsFromAzureKeyvault;
static class Program
{
static async Task Main(string[] args)
{
// Load the appsettings.json file
var builder = new ConfigurationBuilder()
.SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
IConfiguration configuration = builder.Build();
var spnConfig = configuration.GetSection(nameof(SpnConfiguration)).Get<SpnConfiguration>() ?? new SpnConfiguration();
var credential = new ClientSecretCredential(spnConfig.TenantId, spnConfig.ClientId, spnConfig.ClientSecret);
var keyVaultEndpoint = configuration["KeyVaultEndpoint"];
if (string.IsNullOrEmpty(keyVaultEndpoint) || !Uri.IsWellFormedUriString(keyVaultEndpoint, UriKind.Absolute))
{
Console.WriteLine($"KeyVaultEndpoint is missing from the appsettings.json file or it is Invalid Key Vault endpoint: {keyVaultEndpoint}");
return;
}
builder.AddAzureKeyVault(new Uri(keyVaultEndpoint), credential);
// Get the Key Vault endpoint from the appsettings.json : "https://YourKeyVaultName.vault.azure.net/"
configuration = builder.Build();
// Now you can use the configuration object to get values from Azure Key Vault
var secretValue = configuration["SecretKey1"];
}
}
Step 4: Retrieving and Displaying all secrets from Azure Key Vault
Leverage the SecretClient
class to fetch and display each secret stored in Azure Key Vault.
var secretClient = new SecretClient(new Uri(keyVaultEndpoint), credential);
// Get all secrets from the Key Vault
await foreach (SecretProperties secretProperties in secretClient.GetPropertiesOfSecretsAsync())
{
if (secretProperties.Enabled == true)
{
// Get the secret value
KeyVaultSecret secretWithValue = await secretClient.GetSecretAsync(secretProperties.Name);
// Now you can use secretWithValue which is of type KeyVaultSecret
Console.WriteLine($"Secret: {secretWithValue.Name}, Value: {secretWithValue.Value}");
}
}
Step 5: Running the application
Execute the application to load secrets into appsettings.json
and display them in the console.
Conclusion
In this tutorial, we explored how to integrate Azure Key Vault with a .NET application to securely manage application secrets. We also learned how to load secrets into appsettings.json
before application startup and pull all secrets from Azure Key Vault.
Integrating Azure Key Vault with .NET applications enhances the security and manageability of application secrets. This approach not only centralizes secret management but also ensures that sensitive information is never exposed in plaintext within the application's configuration files.
Remember to replace the placeholders in appsettings.json
with your actual Azure Key Vault and service principal details. Also, ensure that the necessary permissions are set in Azure Key Vault to allow the service principal to read secrets.
Full source code
The complete source code for this project can be found at the following GitHub repository: PullSecretsFromAzureKeyvault