(This is part 1 in series on Managing Secrets in a Cloud World. You can read the introduction here.)
In this post we will examine a simple scenario involving the deployment of a .NET based web application to an Azure Web App using Azure Key Vault for secrets management. All the code used for this blog post can be found here.
This simple configuration is appropriate for teams who need tight control over their secrets, even with hardware encryption, but are deploying relatively simple systems. For instance you might be migrating a monolithic web application from on-premise servers to the Azure cloud and need an ops team to manage the secrets instead of developers.
Setting up your Azure Key Vault is a pretty straightforward affair. There are many great how-to’s online (see here and here) so I will not bore you with the details. One thing to note is that as of the time of writing this article there is no way to configure this through the Azure portal so you must use the Powershell tools to manipulate the key vault. However the basic steps to setting up your key vault are:
It’s easy to use the Azure Key Vault from within a .NET web application. There are many good client samples for Key Vault which are available here. In order to access your vault all you need to do is install the NuGet package Microsoft.Azure.KeyVault. This will install the Azure KeyVaultClient. In order to use this it is a simply a matter of creating an authentication token using the ClientId and ClientSecret (pulled from the web.config appsettings in this case) that you recorded earlier:
You then take this token and use the Azure Key Vault Client you installed to retrieve your secrets:
Voila, just like that you have connected your application to your key vault and are able to retrieve your secrets.
The last step in our process is to deploy your application as an Azure Web App. You can follow the steps here to do the basic deployment. What I want to highlight here is a nice feature that is available in this scenario which is the ability to have an administrator set the app settings values from the Azure Portal. In the Azure Portal if you go to the web app you have just deployed and click on the “Configure” tab and then scroll about halfway down the page you will see an area where you can add the app settings.
If you set keys here they will appear in appsettings section of the web.config of the deployed application. Using this method you can provide a set of secrets to your development and test teams for development,build and integration and then have a tightly controlled set of secrets available to production. You might otherwise have to update a few places in your code if you count on the typical app.config method of secrets retrieval.
With our first example of using a secrets container complete, it’s time to cover a concept that’s almost glossed over in the instructions: if you use a container like this (or any of the other ones we will profile) you need a new master secret! That is, how does Azure Key Vault know it should hand your application these carefully controlled secrets in the first place? How does it know who your application is?
We call this “the problem of secret zero”. Your target application needs to wake up with an identity. How do you ferry this secret into the application? The truth is there is no one answer; it will depend on your deployment targets and your deployment methodology. In the example above, the web application is simply configured with one encrypted value. That is, instead of lots of encrypted secrets in a config file, we move to having just one, and the rest are retrieved from the vault.
It might be a step forward, but still represents a vulnerability. Anyone with that secret could retrieve the other secrets. In the Windows/Azure world there are tricks to be played with machine keys or Active Directory identities, but in the next article in the series we’ll see an alternate approach whereby a trusted deployment engine generates a one-time secret zero only during deployment.
Overall the experience with using Azure Key Vault was relatively painless and easy to configure and get working.