ASP.NET Core Configuration â Azure Key Vault
ASP.NET Core Configuration â Azure Key Vault êŽë š
In this article, weâre going to talk about how to protect our sensitive configuration data in the production environment with Azure Key Vault. Previously weâve talked about the Secret Manager and environment variables which we can use to protect our data while in development.
These methods are not suited for production because the values we keep that way are unencrypted and can be easily read if the security is compromised.
Info
The source code for this article can be found on the ASP.NET Core Configuration repo on GitHub (CodeMazeBlog/aspnet-core-configuration
). If you wish to follow along, use the securing-data-locally
(CodeMazeBlog/aspnet-core-configuration
) branch. To check out the finished source code, check out the azure-key-vault
(CodeMazeBlog/aspnet-core-configuration
) branch.
Letâs dive in.
sIntroduction to Azure Key Vault
One of the ways we can keep our secrets secret is by using the Azure Key Vault which is a cloud-based service that keeps cryptographic keys and secrets that our applications and services use. In simple terms, it offers a safe way to store the key-value pairs that we use in our applications.
It uses configuration data flattening as weâve seen with user secrets and environment variables.
Note
In order to use the Azure Key Vault, you must have an active Microsoft Azure subscription.
Microsoft Azure Key Vault configuration provider is the one weâll use this time to migrate our configuration values to the cloud, and later on, connect to the vault and read those values.
The procedure is a bit different for Azure-hosted apps and for non-azure-hosted apps, but weâll focus on the latter because itâs more complicated. Microsoft Azure Key vault offers an easier way for Azure-hosted apps.
There are several steps we need to do in order to use the Azure Key Vault with non-Azure-hosted apps:
- Create Azure Subscription (we wonât talk about this one, we assume you have one)
- Register Azure AD Application
- Create a Certificate and Upload it to Azure AD
- Create the Azure Key Vault
- Import our Existing Secrets
- Connect to the Key Vault through our ASP.NET Core Application
Letâs start by laying some foundation first.
Connecting to Azure Key Vault
In order to connect to our Azure Key Vault, weâll need to register an Azure app. To do that, head on to âAzure Active Directoryâ, then âApp Registrationâ and click on âNew Registrationâ.
The dialog should look like this:
Just give your app a decent name, and click âRegisterâ. Once the app creation is over, you can find it in the apps list. Click on it, and check out the âApplication (client) IDâ. Write it down, since weâre going to need it later.
Next, since we want to connect to the app securely, we need to create and upload a certificate.
Certificate creation has a few steps, and we recommend using OpenSSL to do it since it has all the tools we need.
Creating a certificate with OpenSSL
- If you donât have OpenSSL on Windows download it and - it
- Create a certificate by typing:
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365
- Create a .pfx file from the key and certificate files:
openssl pkcs12 -export -out domain.name.pfx -inkey domain.name.key -in domain.name.crt
- Install pfx locally (double click and go through the wizard)
- Upload cert.pem to Azure AD
To complete step 5, go to the âCertificates & secretsâ in your app, and then âUpload certificateâ.
Write down the certificate thumbprint once the upload is finished.
Creating Azure Key Vault
Now we can move on to creating our vault. Go to the Azure portal home and find the âKey vaultsâ service. Then go to âAddâ and fill in the basic stuff first:
You need to fill in subscription, resource group, name, region, and pricing tier.
After that, navigate to the second tab, Access policy. Hereâs where we need to add the app that weâve created previously. Select the âSecret Managementâ template, and from the âSecret permissionâ dropdown, select âGetâ and âListâ permissions.
Since weâll add our secrets manually, make sure to add your user as a principal too, and give it permissions to set and delete secrets.
Thatâs it, move on to the âReview + createâ tab and click on the âCreateâ button.
Once the process is finished head over to the key vault youâve created and write down the âDNS Nameâ.
At this point you should have three pieces of information:
- Application ID
- Certificate Thumbprint
- DNS Name
Now we can add our secrets to the vault.
Adding Secrets to Azure Key Vault
Now we can finally add our secrets.
Head over to the âSecretsâ tab to the left, and add some secrets:
The process is pretty much straightforward. If you have a problem viewing or adding secrets (grayed out generate/import), double-check your access policies, and click refresh.
As you can see, weâve added some secrets weâve used so far. Weâve flattened the structure by using double dash --
, and weâve changed the âWelcomeMessageâ to âWelcome to the ProjectConfigurationDemo Home Page (Azure)â so we can easily see the change.
Now letâs go back to the code and connect our application to the key vault.
Adding the Vault to our Application
In order to connect our application, we need to extend the configuration a bit.
First, we need to install a NuGet package to support our KeyVault integration:
Install-Package Microsoft.Extensions.Configuration.AzureKeyVault -Version 3.1.7
After that, we need to add the values weâve written down while creating the vault in our appsettings.json:
"Azure": {
"ApplicationId": "85cce826-78e7-405e-8c32-301f71e1ad89",
"CertificateThumb": "6491383027629A9F43F6CB681F299D88293785E0",
"KeyVault": {
"DNS": "https://codemazekeyvault.vault.azure.net/"
}
}
Then, we need to connect to add the Key Vault as a source in the Program
class:
public static IHostBuilder CreateHostBuilder(string[] args) =<
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =<
{
webBuilder.UseStartup<Startup<();
})
.ConfigureAppConfiguration((hostingContext, configBuilder) =<
{
var builtConfig = configBuilder.Build();
using (var store = new X509Store(StoreLocation.CurrentUser))
{
store.Open(OpenFlags.ReadOnly);
var certs = store.Certificates
.Find(X509FindType.FindByThumbprint, builtConfig["Azure:CertificateThumb"], false);
configBuilder.AddAzureKeyVault(
builtConfig["Azure:KeyVault:DNS"],
builtConfig["Azure:ApplicationId"],
certs.OfType<X509Certificate2<().Single());
store.Close();
}
});
This is a standard way of adding an Azure Key Vault by using X509 certificate.
And since weâre adding the vault as the last configuration source, it will override all the previous ones like user secrets or environment variables.
Letâs see the results of our work.
Running the Application
Now if we run the application, we can clearly see that our title has changed:
Our title now shows (Azure) at the end, so that means weâve read the configuration from the key vault successfully.
In order to make this solution even better, we restrict our application to only add the key vault in the production environment:
public static IHostBuilder CreateHostBuilder(string[] args) =<
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =<
{
webBuilder.UseStartup<Startup<();
})
.ConfigureAppConfiguration((context, builder) =<
{
if (context.HostingEnvironment.IsProduction())
{
var builtConfig = builder.Build();
using (var store = new X509Store(StoreLocation.CurrentUser))
{
store.Open(OpenFlags.ReadOnly);
var certs = store.Certificates
.Find(X509FindType.FindByThumbprint,
builtConfig["Azure:CertificateThumb"], false);
builder.AddAzureKeyVault(
builtConfig["Azure:KeyVault:DNS"],
builtConfig["Azure:ApplicationId"],
certs.OfType<X509Certificate2<().Single());
store.Close();
}
}
});
Now when we run our application locally, weâll use the user secrets defined in secrets.json, and weâll use Azure Key Vaults secrets in the production environment.
Thatâs it, awesome isnât it?
sConclusion
In this article, weâve learned how to create an Azure Key Vault to store our secrets for a production environment. Weâve also learned how to connect to the vault from our application and how to use key vault just when running the application in production.
This part wraps up our ASP.NET Core configuration series. You can find other parts of this series on the ASP.NET Core Web API page.