Skip to main content

Written by: Ismaël Diakité
Date Published: 23 December 2023

Image of Azure

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:

  1. Loading Secrets into appsettings.json Before Application Startup: Streamlining the process of securely injecting configuration settings.
  2. 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