Your secrets are safe with Key Vault in ASP.NET CORE Web App on Azure

Are your application secrets being checked in the source control?
Let me introduce you the way to Safeguard your application secrets that will make your application more secure and no more checked in application secrets in the source control. 

What will you learn in this blog: I have been trying to explore how to secure secrets of web application on Azure using Key Vault.  I have been trying to do 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 article which was shown as working as per 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 to be in depth with all small points to be demonstrated via gif 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. In one of our project which was handed over to us was hosted on Azure Cloud as Platform as a Service. We saw  web.config was 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 recommended always store 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 application.
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.

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 that’s 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

    •  Select MVC Template

    •   Add some non-secret configuration in the appsettings.json file as shown below:

    •  Adding an application secret in Secret Manager using visual studio

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:

public class Configurations
    {
        private readonly IConfiguration _configuration;
        public Configurations(IConfiguration configuration)
        {
            _configuration = configuration;
        }
        public string ApplicationName => _configuration["ApplicationName"];
        public string ApplicationSecret1 => _configuration["applicationSecret1"];
    }

Controller Code:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using KeyVaultDemo.Models;
using Microsoft.Extensions.Configuration;

namespace KeyVaultDemo.Controllers
{
    public class HomeController : Controller
    {
        private readonly IConfiguration _configuration;
        public HomeController(IConfiguration configuration)
        {
            _configuration = configuration;
        }

        public IActionResult Index()
        {
            Configurations configurations = new Configurations(_configuration);
            return View(configurations);
        }

        public IActionResult About()
        {
            ViewData["Message"] = "Your application description page.";

            return View();
        }

        public IActionResult Contact()
        {
            ViewData["Message"] = "Your contact page.";

            return View();
        }

        public IActionResult Privacy()
        {
            return View();
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }
}

 

UI Code to show details:

 

Let’s run our application and check whether our application is showing the application secrets on the Home page or not?

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

To speeds things, up I have already created a resource group comprising 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

Let’s now create a Key vault resource in our resource group as shown below.

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

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 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

Code Snippet to read configuration values from the Azure KeyVault 

using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Azure.KeyVault;
using Microsoft.Azure.Services.AppAuthentication;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.AzureKeyVault;

namespace KeyVaultDemo
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
             WebHost.CreateDefaultBuilder(args).ConfigureAppConfiguration((ctx, builder) =>
             {
                 if (ctx.HostingEnvironment.IsProduction())
                 {
                   //DNS Name of key vault
                     var keyVaultEndpoint = "https://domain.vault.azure.net/";
                     if (!string.IsNullOrEmpty(keyVaultEndpoint))
                     {
                         var azureServiceTokenProvider = new AzureServiceTokenProvider();
                         var keyVaultClient = new KeyVaultClient(
                           new KeyVaultClient.AuthenticationCallback(
                              azureServiceTokenProvider.KeyVaultTokenCallback));
                        //Adds an IConfigurationProvider that reads configuration values from the Azure KeyVault
                         builder.AddAzureKeyVault(
                          keyVaultEndpoint, keyVaultClient, new DefaultKeyVaultSecretManager());
                     }
                 }
             }
             )
                 .UseStartup();
    }
}

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 Visual Studio to your Azure Account.

Once you are done with Sign in, all your Azure Subscription services will come under Server Explorer as shown below:

Now, let’s run the application by setting Environment as Production to test whether we are able to connect to the Azure services locally.

Congratulation, 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 :

Allowing Key Vault Access policy to the web app

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

Response: will 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

Then add a new Access policy and search for your web app name

Search for web app name i.e. usingSailleshPawarkeyVault

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 OK button.

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

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

 

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

Publish the web application using the downloaded publish profile

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 application that has to access to otherwise no one can access them. Congratulation we have finally successfully completed the whole requirement. Happy Learning.

If you want to learn Azure Step by Step my honest suggestion would be to go and watch this video.

 

References:
Getting started with Key Vault

One thought on “Your secrets are safe with Key Vault in ASP.NET CORE Web App on Azure

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.