Using Key Vault and Managed Identities with Azure Functions

This article shows how Azure Key Vault could be used together with Azure Functions. The Azure Functions can use the system assigned identity to access the Key Vault. This needs to be configured in the Key Vault access policies using the service principal. By using the Microsoft.Azure.KeyVault and the Microsoft.Extensions.Configuration.AzureKeyVault nuget packages, defining direct references in the Azure Functions configuration is not required. The secrets can be read directly from the Key Vault. This also has the advantage of referencing only the secret and not the direct version of the secret. The latest version of the secret is used (depending on the cache)


Posts in this series


2021-03-07 Update packages and using DefaultAzureCredential for Azure Key vault access

2020-09-18 Updated Configuration, updated Nuget packages

The configuration is setup in the Startup class which inherits from the FunctionsStartup class. We use a string property AzureKeyVaultEndpoint which is used to decide if the Key Vault configuration should be used or not. For local development, Key Vault is not used, user secrets are used. For the Azure deployment, the AzureKeyVaultEndpoint is set with the value of your Key Vault. The configuration is read into the application and added as options to the DI.

using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Azure.KeyVault;
using Microsoft.Azure.Services.AppAuthentication;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using MyAzureFunctions;
using MyAzureFunctions.Activities;
using System;
using System.Reflection;

[assembly: FunctionsStartup(typeof(Startup))]

namespace MyAzureFunctions
    public class Startup : FunctionsStartup
        public override void Configure(IFunctionsHostBuilder builder)

                .Configure<IConfiguration>((settings, configuration) =>

                .Configure<IConfiguration>((settings, configuration) =>

        public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder builder)
            var builtConfig = builder.ConfigurationBuilder.Build();
            var keyVaultEndpoint = builtConfig["AzureKeyVaultEndpoint"];

            if (!string.IsNullOrEmpty(keyVaultEndpoint))
                // might need this depending on local dev env
                //var credential = new DefaultAzureCredential(
                //    new DefaultAzureCredentialOptions { ExcludeSharedTokenCacheCredential = true });

                // using Key Vault, either local dev or deployed
                        .AddAzureKeyVault(new Uri(keyVaultEndpoint), new DefaultAzureCredential())
                        .AddJsonFile("local.settings.json", true)
                // local dev no Key Vault
                   .AddJsonFile("local.settings.json", true)
                   .AddUserSecrets(Assembly.GetExecutingAssembly(), true)

The local.settings.json contains the configurations for the Azure Functions. (No secrets). The AzureKeyVaultEndpoint has no value. If this was set with the URL of a Key Vault, this would activate the Key Vault for local development.

  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "AzureWebJobsSecretStorageType": "Files",
    "ASPNETCORE_ENVIRONMENT": "Development",
    //"AZURE_TENANT_ID": "your tenant",
    // To use the key vault in local debug, the Firewall needs to allow this
    //"AzureKeyVaultEndpoint": "your azure ad tenant"
    "AzureKeyVaultEndpoint": ""
  "MyConfiguration": {
    "Name": "Lilly",
    "AmountOfRetries": 7

The MyConfigurationSecrets class is used to hold the secret configurations.

namespace MyAzureFunctions
    public class MyConfigurationSecrets
        public string MySecretOne { get; set; }
        public string MySecretTwo { get; set; }

The configuration can be used then like any ASP.NET Core application. The services are added in the constructor and can be used as required.

using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace MyAzureFunctions.Activities
    public class MyActivities
        private readonly MyConfiguration _myConfiguration;
        private readonly MyConfigurationSecrets _myConfigurationSecrets;

        public MyActivities(IOptions<MyConfiguration> myConfiguration, 
            IOptions<MyConfigurationSecrets> myConfigurationSecrets)
            _myConfiguration = myConfiguration.Value;
            _myConfigurationSecrets = myConfigurationSecrets.Value;

When deploying, the Azure Functions needs access to the Key Vault. The Azure Functions requires a system assigned Identity. You can activate this, or check that it is created in the Azure portal.

In the Azure Key Vault add a new Access policy.

Search for the required system Identity, ie your Azure Functions, and add the required permissions as your app needs.

The secret configurations are no longer required in the App.Settings of the Azure Functions.

When the functions are called, the actual version is used depending on the cache.


Microsoft Azure Storage Explorer

Microsoft Azure Storage Emulator

Install the Azure Functions Core Tools


Azure CLI

Azure SDK

Visual Studio zure development extensions


  1. […] Using Key Vault and Managed Identities with Azure Functions (Damien Bowden) […]

  2. So you have a dedicated class for the secrets MyConfigurationSecrets
    Presumably the values are in the Key Vault, but in which format?
    Are they entered as individual secrets (one secret for each property on MyConfigurationSecrets)
    Or as a single secret in the form of a json string?

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: