Setting up Azure Key Vault
Key Vault is an Azure module, which lets you safely store your secrets/keys. This way your developers do not have to store credentials or connection strings in the code, but can simpy ask Key Vault to provide them. The application will be handed the password and will be able to log in without the developer even knowing it. Let us create a key vault!
Creating Key Vault
To create a Key Vault (just like you probably expect), simply search for it in Azure. When creating your Key Vault you may specify access policies for your account. For now, you can leave it with default values. You may experiment it with more, once you set up the service.
Registering you app with Azure Active Directory
To enable access to the secrets by Function App, you have to register your app in Azure Active Directory. Only then will you app be able to authenticate with Key Vault.
Open your Function App and navigate to Platform features:
Click on Managed service indentity and register with AAD:
Alternatively, you can use Powershell:
1 |
Set-AzureRmWebApp -AssignIdentity $true -Name $appname –ResourceGroupName $resourcegroupname |
Now that the app is registered with AAD, you can add it in access policies in your Key Vault. To do that, go to access policies:
Click add new, select principal (you app name), specify permissions and click OK:
Now, your app can access your secrets! Even if you have no permission to see the secrets, you still can use them in an app.
Creating a secret
Go to Secrets in the main Settings pane. In there you can enter your passwords, which will be accessable only by specified people/apps. Click on Generate/Import and add a password:
After creating a secret, copy its identifier. This URL can be specified as an environmental variable or pasted into the code like in the example below.
Accessing secrets through Function App
Now, you are ready to create a function and access the secret with code.
Go to Visual Studio and create a new function with HTTP Trigger.
You have to include two namespaces:
1 2 |
using Microsoft.Azure.Services.AppAuthentication; using Microsoft.Azure.KeyVault; |
Next add three lines into the code:
1 2 3 |
var azureServiceTokenProvider = new AzureServiceTokenProvider(); var kv = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback)); string secret = kv.GetSecretAsync(“<Secret URL you have copied>”).Result.Value; |
Also change what the function returns to:
1 |
return (ActionResult)new OkObjectResult($"Your secret is: " + secret); |
Whole code:
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 |
using System; using System.IO; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.Azure.WebJobs; using Microsoft.Azure.WebJobs.Extensions.Http; using Microsoft.AspNetCore.Http; using Microsoft.Azure.WebJobs.Host; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Microsoft.Azure.Services.AppAuthentication; using Microsoft.Azure.KeyVault; namespace MySecretApp { public static class Function1 { [FunctionName("Function1")] public static async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]HttpRequest req, ILogger log) { log.LogInformation("C# HTTP trigger function processed a request."); var azureServiceTokenProvider = new AzureServiceTokenProvider(); var kv = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback)); string secret = kv.GetSecretAsync(“<Secret URL you have copied>”).Result.Value; return (ActionResult)new OkObjectResult($"Your secret is: " + secret); } } } |
After you publish the function, you can run the function from within Azure portal to get your secret:
Hope this helps.
Michał