Managing Secrets
Managing Secrets
Since we are using a RSA key for our authentication stragedy, we’ll need to setup a secret management solution for development and we can also use this opporuntity to setup a production ready solution using Azure Key Vault.
Managing Secrets During Development with Azure Key Vault
Setup Azure Key Vault
To manage our secrets for both development and production we’ll
use Azure Key Vault. Typically you might use something like dotnet user-secrets
but since we’ll have a lot of projects to manage it’s easier to use
something that isn’t tied to a specific project.
If you haven’t already create a key vault in Azure. You can do this with the Azure CLI or the Azure Portal.
# create keyvolt if you haven't alreadyaz keyvault create --name <key-vault-name> --resource-group <resource-group-name> --location <location>After we have the key vault created we can use the following bash script to setup our first secrets. This script will generate a RSA key pair that can be used to sign and verify JWT tokens across our different micro services.
KEY_VAULT_NAME=OneHundredDaysRG_NAME=OneHundredDaysLOCATION=eastus
# generate RSA key pairopenssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048 && \openssl rsa -pubout -in private_key.pem -out public_key.pem &&
# set secretsaz keyvault secret set --vault-name KEY_VAULT_NAME --name "private-key" --value "$(cat private_key.pem)" && \az keyvault secret set --vault-name KEY_VAULT_NAME --name "public-key" --value "$(cat public_key.pem)" && \
# rm from localrm private_key.pem public_key.pemUpdating our App Host
As with our other integrations we’ll add a reference to the hosting package that supports the resource we want to use.
<PackageReference Include="Aspire.Hosting.Azure.KeyVault" Version="8.2.2" />Next we’ll create a resource if we are in publish mode. Otherwise we’ll simply get a connection string to an already existing key vault.
var secrets = builder.ExecutionContext.IsPublishMode ? builder.AddAzureKeyVault(name: "secrets") : builder.AddConnectionString("secrets");Than in our consuming projects we’ll add a reference to the aspire keyvault package.
<PackageReference Include="Aspire.Azure.Security.KeyVault" Version="8.2.2" />To connect locally to the key vault you will need to be signed in
to the az CLI and have the appropriate permissions to access the
key vault.
Since this is something we will want the majority of our projects to
have access to we can create an extension method in our ServiceDefaults
project.
public static class KeyVaultExtensions{ /// <summary> /// Configure Azure Key Vault secrets for the application. /// The key vault URL is retrieved from the connection string named "secrets". /// This must be configured in the AppHost Project. /// </summary> /// <param name="builder">The WebApplication Builder</param> public static void AddAzureKeyVaultSecrets(this IHostApplicationBuilder builder) { if (builder.Environment.IsDevelopment()) { var keyVaultUrl = builder.Configuration.GetConnectionString("secrets"); ArgumentException.ThrowIfNullOrEmpty(keyVaultUrl, nameof(keyVaultUrl)); builder.Configuration.AddAzureKeyVault( new Uri(keyVaultUrl), // using the default azure credential provider will use the az cli new DefaultAzureCredential() ); } else { // Add Azure Key Vault secret values to app configuration (must be the same name you gave the resource in the apphost) builder.Configuration.AddAzureKeyVaultSecrets("secrets"); } }}And in our Program.cs file we can now add the following line to
any of our services:
builder.AddAzureKeyVaultSecrets();