Getting Key Vault Secrets in Azure Functions

One of the common questions around building Azure Functions is how to deal with secrets that a function needs. We know we shouldn’t be putting secrets in the code. Another sometimes satisfactory alternative is place secrets as an app setting. However, since these app settings are retrievable via clear-text through the API/Portal, and would need to be replicated to each function app that needs the secret, some prefer to leverage Azure Key Vault.

Here are the steps to build an Azure Function which can retrieve secrets at runtime. The below uses C# compiled class libraries, but the same underlying pieces can be used with any of the supported languages.

Creating the Key Vault

I followed the instructions here to create a key vault in my Azure Subscription. After the key vault was created I ran this command to add the secret to the vault.

az keyvault secret set --vault-name 'mySuperSecretVault' --name 'eventHub' --value 'Endpoint=MyEventHubConnectionString'

Now authorized identities can retrieve this secret as needed in a central, secure location. One way to access is create my own custom application identity, or “service principal”, which I could use to access the secret. The rub with that approach though is in order to retrieve a valid token for a service principal I need to provide an application secret — which itself is… a secret. With the announcement of Azure managed service identities, I can now give my resource (in this case, a function) an identity and give it permissions just as it were another user.

Configuring the Azure Function

After creating the Azure Function, I enabled a managed service identity for the function app. This will now add an identity in my Azure active directory I can give permissions to any resource I may need.

After enabling the managed service identity, I went into my key vault and added an access policy so my Azure Function app had permissions to read secrets.

The last step is to fetch the secret when I run the app.

Retrieving secrets during function runtime

In C# I just needed to install two NuGet packages into my Azure Function project in Visual Studio: Microsoft.Azure.Services.AppAuthentication and Microsoft.Azure.KeyVault. Then in my code I retrieve the key vault secret with these lines:

var azureServiceTokenProvider = new AzureServiceTokenProvider();
var kvClient = new KeyVaultClient(new     KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback), client);                
string eventHubConnectionString = (await 
kvClient.GetSecretAsync(Environment.GetEnvironmentVariable("EventHubSecretId"))).Value;

You’ll notice I am using an environment variable (application setting) in this case for the key vault secret ID, but that itself is not a secret — just a location of where the secret is stored.

One important thing to note — a single instance of an Azure Function can be initialized and used to run multiple executions. This means not every time the Azure Function runs it’s starting from scratch. You can take advantage of this by using static variables so not every execution requires re-fetching a secret. If I did, I will be incurring some extra resource costs, and potentially would get throttled by Key Vault.

Here is the full example of my Azure Function — notice I only retrieve the secret if that instance of the function app hasn’t yet retrieved it. This means fewer calls to key vault, with all the benefits of retrieving a secret securely in my code.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.