Your Secrets Are Safe With Key Vault In ASP.NET Core Web App On Azure

I have been trying to explore how to secure the secrets of web applications on Azure using Key Vault. In this article, I will walk you through it.

Are your application secrets being checked in the source control?

 
Let me introduce you to the way of safeguarding your application secrets that will make your application more secure, with no more secrets checked in the source control.
 

What will you learn in this article?

 
I have been trying to explore how to secure secrets of web application on Azure using Key Vault. I have been trying to do a small Proof of Concept to try "your secrets are safe with Key Vault in ASP.NET Core Web App" but was failing to implement it in a single shot. I searched various articles which were shown working as per the code but when I implemented them step by step, it never worked.

So finally, after lots of hit and trials, I was finally able to store my web application secrets in the Azure Key Vault.


I will try to cover each and every topic in this small proof of concept with all the small points to be demonstrated via GIF images so that it's easy to understand.
 

Problem Statement

We have been storing all our application related secrets in web.config in ASP.NET whether it has been Web Form or MVC. One of our projects which was handed over to us was hosted on Azure Cloud as Platform as a Service. We saw web.config had been checked in Source control. This is a bad practice to store web app secrets on source control. As we are moving more towards Continuous Integration and Continuous deployment DevOps, it is strongly always recommended to store the app secrets on Azure Key Vault or Application Settings configuration section of Web Apps in Azure.

While in ASP.NET Core, we should store all the application configuration in Environment variables if we are using Web app for containers. This is a standard that is being followed in Enterprise applications.

So, for local development, you can use appsettings.json while in production or QA environment, these configurations will be loaded from Environment variables or applicationSetting in the cloud.

Any new configuration added in appsetting.json should be added in the comment section of Pull Request which should just demonstrate the name of the new configuration and not the value and should be informed to the infrastructure team.

The same is the case with application secrets which we don't want to share with anyone. These kinds of application secrets should be stored in Azure Key vault for production and for local in secrets.json. secrets.json file isn't present in our project folder, it's stored in the OS user profile folder. So, there's no chance it'll get checked into source control.

Case Study

 
We have a web application that we want to deploy on Azure Platform as a service and store all application config to be stored in the Azure Key Vault. Just display the value of secrets on the web page to show that we are able to communicate with Key vault in our web application.

The requirement that will be covered in this blog post,

  1. Configure the web app to communicate with Key vault when deployed.
  2. How to use secrets.json for local dev environment.
  3. Communicate with Key vault in the local environment with Visual studio sign-in identity.
  4. Assign web app to access Azure Key Vault.
  5. Show the Configuration details in the table from Azure Key vault

Dependencies

  1. Azure subscription
  2. Azure Resources needed

    • Web App
    • App Service plan
    • Azure Active Directory
    • Key Vault

Breaking down the problem into small problems first is how we will be proceeding ahead,

  1. Setting up the local environment to use secrets.json and appsettings.json for configuration using ASP.NET core.
  2. Creating Azure Resources needed to for this Demo.
  3. Providing key vault access identity to the web app using power shell command and manual from the portal.

Setting up the local environment to use secrets.json and app settings for configuration using ASP.NET core web application

 
Create an ASP.NET Core project,
 
Your Secrets Are Safe With Key Vault In ASP.NET Core Web App On Azure
 
Select MVC Template,
 
Your Secrets Are Safe With Key Vault In ASP.NET Core Web App On Azure
 
Add some non-secret configuration in the appsettings.json file as shown below,

Your Secrets Are Safe With Key Vault In ASP.NET Core Web App On Azure

Adding an application secret in Secret Manager using Visual Studio,
 
Your Secrets Are Safe With Key Vault In ASP.NET Core Web App On Azure
 

Loading all the application secrets in the application

 
The default IConfiguration builder configures up to 5 configuration providers by default,
  • Appsettings.json
  • An environment-specific appsettings.ENVIRONMENT.json where ENVIRONMENT is the name of the current environment development, staging, etc.
  • User Secrets manager
  • Environment variables for Docker containers

In order to demonstrate the same let's run the application where we have configured our application secrets in appsettings.json and secrets.json.

Create a class named Configurations and use IConfiguration interface to load the secrets as shown below,

  1. using Microsoft.Extensions.Configuration;  
  2. using System;  
  3. using System.Collections.Generic;  
  4. using System.Linq;  
  5. using System.Threading.Tasks;  
  6.   
  7. namespace KeyVaultDemo.Models  
  8. {  
  9.     public class Configurations  
  10.     {  
  11.         private readonly IConfiguration _configuration;  
  12.         public Configurations(IConfiguration configuration)  
  13.         {  
  14.             _configuration = configuration;  
  15.         }  
  16.   
  17.         public string ApplicationName => _configuration["ApplicationName"];  
  18.         public string ApplicationSecret1 => _configuration["applicationSecret1"];  
  19.         public string ApplicationSecret2 => _configuration["applicationSecret2"];  
  20.   
  21.     }  
  22. }  
Controller Code
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Diagnostics;  
  4. using System.Linq;  
  5. using System.Threading.Tasks;  
  6. using Microsoft.AspNetCore.Mvc;  
  7. using KeyVaultDemo.Models;  
  8. using Microsoft.Extensions.Configuration;  
  9.   
  10. namespace KeyVaultDemo.Controllers  
  11. {  
  12.     public class HomeController : Controller  
  13.     {  
  14.         private readonly IConfiguration _configuration;  
  15.         public HomeController(IConfiguration configuration)  
  16.         {  
  17.             _configuration = configuration;  
  18.         }  
  19.   
  20.         public IActionResult Index()  
  21.         {  
  22.             Configurations configurations = new Configurations(_configuration);  
  23.             return View(configurations);  
  24.         }  
  25.   
  26.         public IActionResult About()  
  27.         {  
  28.             ViewData["Message"] = "Your application description page.";  
  29.   
  30.             return View();  
  31.         }  
  32.   
  33.         public IActionResult Contact()  
  34.         {  
  35.             ViewData["Message"] = "Your contact page.";  
  36.   
  37.             return View();  
  38.         }  
  39.   
  40.         public IActionResult Privacy()  
  41.         {  
  42.             return View();  
  43.         }  
  44.   
  45.         [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]  
  46.         public IActionResult Error()  
  47.         {  
  48.             return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });  
  49.         }  
  50.     }  
  51. }  
UI Code

Your Secrets Are Safe With Key Vault In ASP.NET Core Web App On Azure

Let's run our application and check whether our application is showing the application secrets on the homepage or not.

We are able to successfully load the configuration from appsettings.json and secrets.json files in our web application. Let's now proceed ahead and start our pending task of loading user secrets from the Key Vault. In order to achieve the same, I will create the needed Azure resources.

Your Secrets Are Safe With Key Vault In ASP.NET Core Web App On Azure 

To speeds things up, I have already created a resource group consisting of the web app which uses an instance of app service plan in another resource group and I already have Azure Active Directory that would be needed in future references.

Azure Active Directory

 
Your Secrets Are Safe With Key Vault In ASP.NET Core Web App On Azure 

Let's now create a Key Vault resource in our resource group, as shown below.

Your Secrets Are Safe With Key Vault In ASP.NET Core Web App On Azure

Now we are done with resource creation. Let us create some secrets on Key vault manually from the portal.

Your Secrets Are Safe With Key Vault In ASP.NET Core Web App On Azure

Once the above steps are completed, let's try to configure and consume key vault on our ASP.NET Core application. Before moving ahead, install two NuGet dependencies we need to work with while working on the Key Vault.

  • Microsoft.Azure.KeyVault Version:3.0.3
  • Microsoft.Extensions.Configuration.AzureKeyVault Version:2.1.0
  • Microsoft.Azure.Services.AppAuthentication Version: 1.0.3

Here is the code snippet to read configuration values from the Azure KeyVault.

  1. using Microsoft.AspNetCore;  
  2. using Microsoft.AspNetCore.Hosting;  
  3. using Microsoft.Azure.KeyVault;  
  4. using Microsoft.Azure.Services.AppAuthentication;  
  5. using Microsoft.Extensions.Configuration;  
  6. using Microsoft.Extensions.Configuration.AzureKeyVault;  
  7.   
  8. namespace KeyVaultDemo  
  9. {  
  10.     public class Program  
  11.     {  
  12.         public static void Main(string[] args)  
  13.         {  
  14.             CreateWebHostBuilder(args).Build().Run();  
  15.         }  
  16.   
  17.         public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>  
  18.              WebHost.CreateDefaultBuilder(args).ConfigureAppConfiguration((ctx, builder) =>  
  19.              {  
  20.                  //if (ctx.HostingEnvironment.IsProduction())  
  21.                  //{  
  22.                      var keyVaultEndpoint = "https://appkeyvaultdemo.vault.azure.net/";  
  23.                      if (!string.IsNullOrEmpty(keyVaultEndpoint))  
  24.                      {  
  25.                          var azureServiceTokenProvider = new AzureServiceTokenProvider();  
  26.                          var keyVaultClient = new KeyVaultClient(  
  27.                            new KeyVaultClient.AuthenticationCallback(  
  28.                               azureServiceTokenProvider.KeyVaultTokenCallback));  
  29.                          builder.AddAzureKeyVault(  
  30.                           keyVaultEndpoint, keyVaultClient, new DefaultKeyVaultSecretManager());  
  31.                      }  
  32.                  //}  
  33.              }  
  34.              )  
  35.                  .UseStartup<Startup>();  
  36.     }  
  37. }  

This code will add a provider to read configuration from the Azure Key Vault.

Communicate with Key vault in the local environment with Visual studio sign-in identity

Visual studio sign-in identity allows you to connect with Azure Services on the local environment; this is done with the help of dependency that we have installed priorly Microsoft.Azure.Services.AppAuthentication.

First sign in on Visual Studio to your Azure Account.

Your Secrets Are Safe With Key Vault In ASP.NET Core Web App On Azure
 
Once you are done with the Sign-in, all your Azure Subscription Services will come under Server Explorer, as shown below.
Your Secrets Are Safe With Key Vault In ASP.NET Core Web App On Azure
 
Now, let's run the application by setting the Environment as Production to test whether we are able to connect to the Azure services locally.
 
Your Secrets Are Safe With Key Vault In ASP.NET Core Web App On Azure

Your Secrets Are Safe With Key Vault In ASP.NET Core Web App On Azure

Congratulations, we are successfully able to authenticate to Azure services using the developer's Azure Active Directory/ Microsoft account during development.

Now let's try to complete our last and most important task of deploying the app on Azure and set read policy for Azure Key vault from our web application.

Using PowerShell command,

az webapp identity assign --name "usingSailleshPawarkeyVault" --resource-group "sailleshpawarRG"

This will enable the web app's managed service identity to On.

Response

Your Secrets Are Safe With Key Vault In ASP.NET Core Web App On Azure

Allowing Key Vault Access policy to the web app:

az keyvault set-policy --name usingSailleshPawarkeyVault--object-id PrincipalId --secret-permissions get

The response will be the set of permissions and modes of Azure Key Vault.

Using the Azure portal, allow Key vault access to the web app using the portal.

... Go to Key vault resource and click on Access policies,
 
Your Secrets Are Safe With Key Vault In ASP.NET Core Web App On Azure
 
Then add a new Access policy and search for your web app name,
 
Your Secrets Are Safe With Key Vault In ASP.NET Core Web App On Azure
 
Search for web app name i.e. usingSailleshPawarkeyVault,
 
Your Secrets Are Safe With Key Vault In ASP.NET Core Web App On Azure
 
Your Secrets Are Safe With Key Vault In ASP.NET Core Web App On Azure
 
Note
Make sure you do not enter any application name in Authorized application attribute...

... if you do the application will not be able to read secrets and will fail and throw Process Id failure exception.

Give permission to the application for Key vault and then click on the OK button.

Now, enable the managed identity for the web application as shown below:

Go to your app service and click on Identity and enable system assign,

Your Secrets Are Safe With Key Vault In ASP.NET Core Web App On Azure
 
Your Secrets Are Safe With Key Vault In ASP.NET Core Web App On Azure 

Once the above steps are done now let's publish our application on Azure portal by following the below steps,

Your Secrets Are Safe With Key Vault In ASP.NET Core Web App On Azure 

Publish the web application using the downloaded publish profile

Your Secrets Are Safe With Key Vault In ASP.NET Core Web App On Azure

Finally, you can see we are able to connect to Azure key vault and secure our app secrets from anyone. The Key vault secret will be available to the users or applications that have access,  otherwise no one else can access them.

Congratulations, we have finally successfully completed the whole requirement. Happy Learning!!

References