In the software world, there is a special importance to security. For example – If I want to purchase a software like Visual Studio Ultimate Edition, I first download its demo version which lets me use the software for a certain period of time and once that time is over, it asks me for a valid license key. So in this context, the software vendor has used the key to safeguard the software. Let’s take a look at another example and to keep it easy, let’s talk about Azure. If one wants to access any set of services provided by Azure storage, then the user needs to have the access key of the storage account. In this example, access key is used to safeguard storage account and its services.
Recent changes to Azure services seem to be mostly focusing on the encryption e.g. encryption of storage services, built in encryption capabilities in SQL Azure, disk encryption option of Azure VMs etc. and when there is an encryption, the encryption keys and their management come into the picture, you want to make sure that you store your encryption keys in the right and secure place and be assured about organization compliance requirements.
Now to start with Azure key vault, let me explain it in layman’s term i.e., Azure key vault provides a store where you can manage all your keys and secrets effectively. Now wait, what is the difference between your keys and secrets? It’s simple concept – keys are referring to terms like your encryption keys, however secrets can be any sensitive data like your SQL database connection string or storage access credentials etc.
Let us see the dictionary meaning of vault – it is either a dome or a treasury, which when translated in to azure world gives correct impression i.e. treasury of my keys and secrets. It acts as a central store for all my sensitive information which can be stored secretly and can be retrieved based on permissions.
Azure key vault service is backed by HSM i.e. hardware security modules using certain state of the art algorithms. In simple words – HSM is a mechanism which is used to manage and store these cryptographic keys securely. You can certainly go ahead and read more about it if you are interested in details of HSM and algorithms it uses.
Let’s see what are the capabilities azure key vault offers,
Suppose I as an administrator of my azure subscription logs in to the azure portal, I will be able to create azure key vault service and using it I will be able to perform operations below,
- Create, import or delete keys in key vault
- Authorize users to access keys and their secrets
- Configure and monitor key usage
To access the keys and secrets stored inside the key vault, the requesting applications have to be added in Azure active directory and it also needs to have permissions to read keys and secrets in azure key vault. We will take a detailed look at it later in this article.
Here is how it can be drawn to give high level conceptual idea,
I the real world, let’s take a look at how things can work in conjunction with Azure key vault.
A subscription administrator or power use in an organization creates Azure key vault and creates some keys and adds secrets in it. These secrets can be consumed by many applications in an organization.
Now suppose there is this team of application developers who are deploying their application on Azure. The application talks to azure key vault and has its architectural model in place to communicate to key vault and read secrets out of it.
This application first has to be registered with Azure AD so that using AD’s client application ID access can be grant to azure key vault services.
Once all the setup is in place as shown in image above, and now power user wants to update some secret’s value stored inside the key vault, then in this case power user doesn't have to inform about the update to developers or application owners which actually saves re-deployment efforts, e.g. power user rotates the storage access key and updates it in key vault, and since the application already has the model to communicate to key vault based on its endpoint URI or name, so even though the key / secret is updated – the application always picks up the latest value.
For the demo, we will considerthe exact same example, i.e. we will add storage access key in key vault as a secret, we will develop a web application which reads the secret from azure key vault. We will rotate storage access key and then update our secret’s value with updated access key and see if our deployed web application still picks up the latest value.
How to set up Azure key vault
Let’s see how we can set up Azure key vault and configure applications to use the secrets from the vault.
First thing first, as of writing this article – the only interface available to work with key vault is the Azure PowerShell. You can download it from here and make sure that it has azure key vault cmdlets.
Note that currently Azure has two modes of managing resources, i.e. standard and other is resource manager. We will be using Azure PowerShell with RM mode – this article focuses on key vault assuming that you have basic understanding of Azure resource manager mode if not, it is highly recommended that you take a look at it, e.g. here.
We will log in to Azure subscription and switch to Azure RM mode,
Below are the Azure PowerShell cmdlets which lets you do it,
PS:> Login-AzureRmAccount
PS:> Get-AzureRmAccount
Next, we will create a resource group under which we will be creating our key vault service
PS:> New-AzureRmResourceGroup –Name 'BhushanKeyVaultRG' –Location 'SouthEast Asia'
Now we have created resource group with name BhushanKeyvaultRG and hosted in south east asia DC, we will go ahead and create Azure key vault service in it
PS:> New-AzureRmKeyVault -VaultName 'BhushanKeyVault' -ResourceGroupName 'BhushanKeyVaultRG' -Location SouthEast Asia'.
After successful creation of key vault, it returns details of it. We can make a note of our key vault URI which is used later in this article
We will now create a storage account within same resource group and name it as bhushandemostorageaccount. To speed up things, I will go ahead and create it using azure portal and host it in same DC i.e. SouthEast Asia.
Now let’s add the access key of the storage account in key vault as a secret and name it as
BhushanDemoStoragePrimaryKey
It can be done through command below,
PS:> $secretvalue = ConvertTo-SecureString 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxyxxxxxxxxxxxxxxxxxxxx==' -AsPlainText –Force
PS:> Set-AzureKeyVaultSecret -VaultName 'BhushanKeyVault' -Name 'BhushanDemoStoragePrimaryKey' -SecretValue $secretvalue
Note that we are converting the access key to secure string and then storing it in key vault using above cmdlets.
Now that we have added the access key in the key vault, let’s create a web application which consumes this secret from key vault.
I will create a MVC web application and simple after creating it I will hit F5 so that it runs in IIS express giving me it’s URL which I will need to add in Azure active directory.
Suppose my application is running on URL – http://locahost:49993/
We will need to add this application in Azure active directory so that it can be given privileges to access Azure key vault.
Browse to Azure active directory in your subscription and click on applications tab.
Click on the add button to register the application in AD
As this is a demo app so I won’t be paying much attention to required metadata.
Click ok and your application will be added to AD and you will be redirected to dashboard of it.
Click on the configure tab and note down the client ID, we will be using it later in this article.
Also, on the same tab – browse to keys section and select duration, once you save your changes – you will be shown the key.
Now the application is registered with active directory, however our key vault still is unaware of our application so let’s go ahead and introduce them to each other.
I have used below PowerShell command which grants all permission to web application so that read all keys and secrets in our key vault. You can control these permissions and grant only those permissions to applications which are required by them.
Set-AzureRmKeyVaultAccessPolicy -VaultName 'BhushanKeyVault' -ServicePrincipalName ‘xxxxxxxx-xxxx-xxxx-xxxx-6eb4e8975211' -PermissionsToKeys all -PermissionsToSecrets all –ResourceGroupName 'BhushanKeyVaultRG'
And now key vault knows our web application and allows it to read stored keys and secret.
Now let’s go ahead and write some code in our web application.
First, install below nuggets packages in the solution, one is to communicate to Azure AD and other is to perform azure key vault related actions.
And
Also let’s add few entries in our web configuration files as,
Note that ClientId is set to the value which was shown as ClientID shown in the azure active directory and client secret is set to key value generated after setting and saving duration on same page in Azure AD.
For this demo, we can take a look at pre-built library shared at and use it to speed up things. It shows how basic actions to azure key vault can be performed. ( I have used some of the code from this library).
I have copied few classes from the HelloKeyVault.csproj to our web application project, copied some helper functions like GetAccessToken and GetHttpClient, also installed System.Net.Http.Formatting nugget.
Add a DemoController and Index view and modify default routing of the application. We will be adding our logic in this action method which will fetch stored secret.
public class DemoController : Controller
{
public ActionResult Index()
{
var vaultAddress = WebConfigurationManager.AppSettings["VaultUrl"];
// Register authentication call back - this would be executed for any request to Azure key vault.
KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetAccessToken));
var secret = keyVaultClient.GetSecretAsync(vaultAddress, "BhushanDemoStoragePrimaryKey", null).GetAwaiter().GetResult();
var storagePrimaryAccessKey = secret.Value;
return View();
}
public static async Task<string> GetAccessToken(string authority, string resource, string scope)
{
var clientId = WebConfigurationManager.AppSettings["AuthClientId"];
var clientSecret = WebConfigurationManager.AppSettings["AuthClientSecret"];
ClientCredential clientCredential = new ClientCredential(clientId, clientSecret);
var context = new AuthenticationContext(authority, TokenCache.DefaultShared);
var result = await context.AcquireTokenAsync(resource, clientCredential);
return result.AccessToken;
}
}
}
Code is quite self-explanatory, we are reading Client Id and secret from web configuration file and using it to get the access token from the authenticating authority.
Note that this is not the best way to get the authentication token, there is certificate based mechanism which you can use to achieve the same. You can take a look at the pre-built library for more explanation.
Once the above code is set and application is deployed on azure, later even if vault administrator or power user changes the value of secret (e.g. by rotating storage access key periodically) it doesn’t impact the application and it will always read the latest value of storage access key.
Logging in Azure Key Vault
Now that you have created key vault and started adding your keys and secrets in it, you might want to monitor when and who is accessing your secure data.
Logging works in similar to the way SQL Azure creates logs, i.e. in Azure storage.
Since we have already created our storage account, we will use the same for storing key vault logs.
Once we configure logging in key vault, a container named ‘insights-logs-auditevent’ is created in specified azure storage.
Retention and access to the information stored in a container has to be managed by you e.g. using standard protection techniques.
Let’s set up logging to our Azure key vault
PS:> $keyvault = Get-AzureRmKeyVault -VaultName 'BhushanKeyVault'
PS:> $storageaccount = Get-AzureRmStorageAccount -StorageAccountName 'bhushandemostorage'
You can get the key vault resource Id and storage account Id using above parameters e.g.
$keyvault.ResourceId and $storageaccount.Id
We will be using these parameters in next command
Set-AzureRmDiagnosticSetting -ResourceId '/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/BhushanKeyVaultRG/providers/Microsoft.KeyVault/vaults/BhushanKeyVault' -StorageAccountId '/subscriptions/xxxxxxxx-xxxxx-xxxxx-xxxx-xxxxxxxxxxx/resourceGroups/bhushankeyvaultrg/providers/Microsoft.Storage/storageAccounts/bhushandemostorage' -Enabled $true -Categories AuditEvent
Now the logging has been enabled on azure key vault.
What is logged
- All authenticated REST API requests will be logged. (including access denied requests).
- Actions on key vault e.g. creation, deletion, setting key value access policies etc
- Actions on the keys and secrets e.g. encrypt, decrypt, sign, verify etc.
Let’s access the secret stored in key vault using our web application again and see what information is logged in the logging container.
It stores a JSON record in a deep nested structure of containers,
If you explore the container and take a look at the JSON log file, you will observe that Information like request Uri, client IP address etc. information is logged.
Read more articles on Azure: