Securing Azure KeyVault connections using Managed Identity

In the previous post we saw that we can connect to Azure KeyVault from ASP.NET Core application using the default credentials. If you haven't read that, please find it here

Manage application settings with Azure KeyVault

But this is not a secure way of doing things obviously due to security concerns. In order to overcome this, the recommended approach is used to Managed Identity in Azure. This will work only if your application is hosted in Azure. It is similar to a service principal which connects on your app's behalf to communicate with other resources

Create Managed Identity

The first step is to create a Managed Identity resource in Azure and then give read permission for this identity in the Keyvault which you need to communicate

You can refer to the official documentation given below to perform this step

Managed identities for Azure resources

Connecting to KeyVault from ASP.NET Core Web App

Add a Nuget package called Azure.Identity

<PackageReference Include="Azure.Identity" Version="1.6.0" />

Modify the entries in your appsettings.json to add entries for the key vault URL and managed identity id

 "AzureKeyVault": {
"keyvault-url": "https://gab22demo-rg.vault.azure.net/",
"mi-client-id": "72b0cc31-b3f9-4230-9e12-bd3f5c793e55"
},

Now, in the startup code, add the following snippet

var keyVaultURL = hostingContext.Configuration.GetSection("AzureKeyVault:keyvault-url").Value;
var miClientId = hostingContext.Configuration.GetSection("AzureKeyVault:mi-client-id").Value;
var client = new SecretClient(new Uri(keyVaultURL), new ManagedIdentityCredential(miClientId));
config.AddAzureKeyVault(client: client, new KeyVaultSecretManager());

What we are doing basically here is

  • adds the KeyVault as a configuration provider
  • sets up the connection to key vault using AddAzureKeyVault method

Once you complete this step, you will be able to access the key vault references in the same way you access values from other configuration providers such as appsetting.json

A sample snippet is given below. Here we are using the IConfiguration instance to read the value  DBConnection which is being fetched from the vault during the startup phase.

private readonly ILogger<HomeController> _logger;
private readonly IConfiguration _configuration; 

public HomeController(ILogger<HomeController> logger, IConfiguration configuration)
{
    _logger = logger;
    _configuration = configuration;
}

public IActionResult Index()
{
    List<Product> products = new();
    using (var db = new GABDemoDbContext(_configuration["DBConnection"]))
    {
        products = db.Product.OrderBy(x => x.Name).ToList();
    }
    return View(products);
}



No Comments

Add a Comment