Manage application settings with Azure Keyvault
Securing your data and application configuration should of prime importance for an applicatio developer/architect and needs to be taken care of during the design phase itself. It is always better to take preventive steps rather than doing firefighting after an incident. There are lot of best practices out there to safeguard the data, but from time to time we ignore/forget to securely store app configuration settings.
Related Articles
Very often developers tend to store hard coded passwords, tokens, authorization keys etc in the code or in the application configuration files and then commits the code into the version control. If your repo is publically avialable or some bad actors got access to it, then you may end up in lot of trouble. There are automated bots which looks for these kind of information by scanning the repos publically available in GitHub or BitBucket and then targets your infrastucture with these credentials
Securing the configuration settings
There are lot of ways you can make that secure, for example by encrypting the entries in the configuration files or by keeping those sensitive information in some other medium such as a database. Another option is to rely on resources provided by cloud vendors such Micrsoft or Amazon.
Azure KeyVault is a one such cloud service provided by Microsoft for secure storing and accessing not only secrets but also certificates, keys, passwords etc. Please refer this offical document for more details about Azure KeyVault. Apart from storing it securely, KeyVault provides additional features such as access control, audit logging, versioning, validity and much more. With the help of these features we can make sure that only authorized personal/app has access to the data with proper auditing and expiration controls.
Creating a KeyVault in Azure
We can create a resource in Azure in a number of ways, here I am going to show you how to create an vault from the portal as well as with commands using Azure CLI
.
Portal
Just type in Key Vault
in the search bar at the top and select Key Vaults
from the results. From the next page, select the Create
option and you will get a window like the one below. There, just select the Resource Group, specify a name for the key vault, region and pricing tier and leave the rest with the default values
Azure CLI
az keyvault create --name "gab22demo-rg" --resource-group "GAB22RG" --location "SouthIndia"
Creating a secret
Before you can add a secret in the key vault, you will need to give yourself access for either adding or managing it. In order to do that, you can go to Access Policies
from the left menu under your key vault and then select Add Access Policy
. Since we are dealing only with secrets, we will only select the necessary permissions needed for the same and then the identity to give access to
CLI Command
az keyvault secret set --vault-name "gab22demo-rg" --name "DBConnection" --value ""
Reading secrets in your code
So we have created the key vault and added a secret in the vault to store the database connectionstring. Now, let's how we can read this connection string from the vault and establish a connection to the database from the code base. For this post, I am going to use a .NET6 Web application for the demo purpose.
In Azure, while creating the key vault it exposes api endpoint which can be used in our code to establish a connection to the vault for performing various operations. To get started, we will need to install a nuget package named Microsoft.Extensions.Configuration.AzureKeyVault
We are going to store the key vault endpoint in the config file and will load it into the configuration collection during the bootstrapping phase
So, let's add an entry in the appsettings.json
file as shown below
"AzureKeyVault": {
"keyvault-url": "https://gab22demo-rg.vault.azure.net/"
},
Now, in the startup code, add the following snippet
builder.Host
.ConfigureAppConfiguration((hostingContext, config) =>
{
AzureServiceTokenProvider azureServiceTokenProvider = new();
KeyVaultClient keyVaultClient = new(
new KeyVaultClient.AuthenticationCallback(
azureServiceTokenProvider.KeyVaultTokenCallback
));
config.AddAzureKeyVault(hostingContext.Configuration.GetSection("AzureKeyVault:keyvault-url").Value,
keyVaultClient,
new DefaultKeyVaultSecretManager());
});
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
Sample snippet is given below. Here we are using the IConfiguration
instance to read the value for DBConnection
which is being fetched from the vault duing the startup phase.
private readonly ILogger _logger;
private readonly IConfiguration _configuration;
public HomeController(ILogger logger, IConfiguration configuration)
{
_logger = logger;
_configuration = configuration;
}
public IActionResult Index()
{
List products = new();
using (var db = new GABDemoDbContext(_configuration["DBConnection"]))
{
products = db.Product.OrderBy(x => x.Name).ToList();
}
return View(products);
}