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)

Code: https://github.com/damienbod/AzureDurableFunctions

Posts in this series

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.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

**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)

{

**var** keyVaultEndpoint = Environment.GetEnvironmentVariable(``"AzureKeyVaultEndpoint"``);

**if** (!``**string**``.IsNullOrEmpty(keyVaultEndpoint))

{

// using Key Vault, either local dev or deployed

**var** azureServiceTokenProvider = **new** AzureServiceTokenProvider();

**var** keyVaultClient = **new** KeyVaultClient(``**new** KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));

**var** config = **new** ConfigurationBuilder()

.AddAzureKeyVault(keyVaultEndpoint)

.SetBasePath(Environment.CurrentDirectory)

.AddJsonFile(``"local.settings.json"``, **true**``)

.AddEnvironmentVariables()

.Build();

builder.Services.AddSingleton<IConfiguration>(config);

}

**else**

{

// local dev no Key Vault

**var** config = **new** ConfigurationBuilder()

.SetBasePath(Environment.CurrentDirectory)

.AddJsonFile(``"local.settings.json"``, **true**``)

.AddUserSecrets(Assembly.GetExecutingAssembly(), **true**``)

.AddEnvironmentVariables()

.Build();

builder.Services.AddSingleton<IConfiguration>(config);

}

builder.Services.AddScoped<MyActivities>();

builder.Services.AddOptions<MyConfiguration>()

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

{

configuration.GetSection(``"MyConfiguration"``).Bind(settings);

});

builder.Services.AddOptions<MyConfigurationSecrets>()

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

{

configuration.GetSection(``"MyConfigurationSecrets"``).Bind(settings);

});

}

}

}

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.

1

2

3

4

5

6

7

8

9

10

11

12

13

{

"IsEncrypted"``: **false**``,

"Values"``: {

"AzureWebJobsStorage"``: "UseDevelopmentStorage=true"``,

"AzureWebJobsSecretStorageType"``: "Files"``,

"FUNCTIONS_WORKER_RUNTIME"``: "dotnet"``,

"AzureKeyVaultEndpoint"``: ""

},

"MyConfiguration"``: {

"Name"``: "Lilly"``,

"AmountOfRetries"``: 7

}

}

The MyConfigurationSecrets class is used to hold the secret configurations.

1

2

3

4

5

6

7

8

**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.

#function

Using Key Vault and Managed Identities with Azure Functions
8.55 GEEK