This is part three in my series on Key Vault if you haven't yet, make sure to read the Intro and Creating and accessing an Azure Key Vault to get the basic idea of the concept.

Get secrets from Azure Key Vault

Finally, it's time to look at some code. In the previous posts I created the Key Vault and got an Application Id and a Token. Those together with the url to the Key Vault will be the basis for this post.

The approach I would usually use for getting secrets is to set everything up in a bootstrapper (where you setup your app, like Startup.cs), and load the needed settings into some settings object, that will be registered with your Dependency Injection framework. This example will show you the shortest way of getting a key in a C# file, be it a Controller, a Startup class or the like.

NuGet

The hard part of the code for accessing Key Vault has already been done for us. Add the following to your project

Combining the dots

The first thing we need to do is to obtain a new Token that can be used for a limited amount of time and allows our service principal to access our Key Vault. This is done via a callback later, but the method looks like this

public static async Task GetToken(string authority, string resource, string scope)
{
    var authContext = new AuthenticationContext(authority);
    ClientCredential clientCred = new ClientCredential(ConfigurationManager.AppSettings["ClientId"],
                ConfigurationManager.AppSettings["ClientSecret"]);
    AuthenticationResult result = await authContext.AcquireTokenAsync(resource, clientCred);

    if (result == null)
        throw new InvalidOperationException("Failed to obtain the JWT token");

    return result.AccessToken;
}

See full code example at GitHub

That's it for obtaining the access token - I've taken two settings from config, one called ClientId, which is what we also referred to as Application Id, and one called ClientSecret, which is the token we created for our Service Principal in the previous blogpost.

Using the code above is done when initializing the Key Vault object. we do the following, where I've added the GetToken method in a TokenBasedAccessHelper class:

KeyVaultClient keyVaultClient = new KeyVaultClient(
    new KeyVaultClient.AuthenticationCallback(
        TokenBasedAccessHelper.GetToken));

See full code example at GitHub

With this in place, we now have a KeyVaultClient, which we can use to obtain secrets from our Key Vault. The client has methods like GetSecretAsync, which just takes an identifier to the secret. 

Notes about accessing Key Vault, performance wise

Generally, we are swapping out accessing the local web/app.config for getting secrets (which is wicked fast, as it is read into memory), with http-based calls which also requires getting a token before accessing. This means that accessing the Key Vault is very much slower than just taking the secrets from .config file. That means that we need to make a strategy for fetching the secrets. 

I've found in my team that fetching all secrets needed at startup works nice. We will add code for accessing the Key Vault as one of the first things in our bootstrappers, when we setup services for Dependency Injection. Settings will either be read and added to the services that uses them, or we create a dedicated object for storing the secrets.

In the two blog post about setting up an Umbraco site and an Umbraco Cloud site with Key Vault, ill dive deeper into how that could be done.

References