Azure Functions Tips: how to store the Functions App keys into KeyVault
Tags: azure, azurefunctions
Published: 2023-05-17 09:28:00

## Introduction
In a [previous post](https://dev.to/massimobonanni/azure-functions-tips-where-are-our-function-app-keys-ii0), we talked about Function App keys and the default store.
The default store for all the keys in your Function app is a Storage Account. You can change it, you can have two different Storage Accounts for the keys and for other stuff of your Function App, but it is a Storage Account.
One of the best practices about secrets management in Azure is to store them in a Key Vault and the Function App keys are, at the end, secrets.

## Key Vault as keys store
You can change the service you use to store the Function App keys using the `AzureWebJobsSecretStorageType` config value.
Setting this value in the Function App configuration, you che choose the following services:

- `blob`: this is the default value and allows you to use Storage Account as secret store (as show in the previous [post](https://dev.to/massimobonanni/azure-functions-tips-where-are-our-function-app-keys-ii0));

- `files`: use the file system to persist the secrets. This is the default for the function runtime v.1.x;

- `keyvault`: using this value, you can store the keys into a Key Vault;

- `kubernetes`: this is supported only if your functions run in Kubernetes.

In our case, we set the value on `keyvault` and we use `AzureWebJobsSecretStorageKeyVaultUri` key to store the Key Vault reference.

![The Function App configuration to use Key Vault as a secret store](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l2o47w0fl7zix94wnkrz.png)

## It's just identity
Now you set the Key Vault as secret store, but all this is useless if the function app doesn't have privileges to access the Key Vault itself.

You can use both Managed Identity or Service Principal (App Registration) to provide permission on the Key Vault site.

### Managed Identity
In this scenario we can either use a System-assigned or a User-assigned Managed Identity.
In the first case, we don't need to do anything except configure the access credentials on the Key Vault service (we'll see later).
If, on the other hand, we have defined our Function App as a User-assigned Managed Identity, we need to retrieve the client id of the identity and use it in the `AzureWebJobsSecretStorageKeyVaultClientId` configuration.
To retrieve the Client ID, you can use the portal:

![The client id location in the Managed Identity page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uv53xahinyaap0mt6qv4.png)

or you can use the CLI command:

```bash
az identity show --name <identity name> --resource-group <resource group name> --query "{ClientID:clientId}"
```

Once you have the client id, you add it to the Function App configuration:

![Client ID configuration in the Azure Portal](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l5lf8yqf251o459mx487.png)

### App Registration
If you need, you can also use a Service Principal (App Registration).
In this scenario, you need to have Client ID, Tenant ID and Client Secret (as usual) from the portal and, then add the following settings in the Function App configuration:

- `AzureWebJobsSecretStorageKeyVaultClientId`

- `AzureWebJobsSecretStorageKeyVaultClientSecret`

- `AzureWebJobsSecretStorageKeyVaultTenantId`

**Note**: System-assigned Managed Identiy works perfectly with runtime version 3.x and 4.x, while the other two (User-assigned and App Registration) work only with runtime 4.x.

### Set the right credential
Once you have an identity for your Function App you need to set the right credential into the Key Vault.
The Function App needs to:

- retrieve the list of the keys (it shows you the keys in the portal);
- read a key (it need to check the single key every time you make a call);
- add/update a key (you can add or change an existing key from the portal);
- delete a key (you can remove a key).

You can configure these permission using RBAC or access policy.
If you use RBAC, the right role for the Function App need to have, at least, the following DataActions:

- `Microsoft.KeyVault/vaults/secrets/delete`
- `Microsoft.KeyVault/vaults/secrets/getSecret/action`
- `Microsoft.KeyVault/vaults/secrets/setSecret/action`
- `Microsoft.KeyVault/vaults/secrets/readMetadata/action`

You can use the built-in role "Key Vault Secrets Officer" even it has more operations than you need. 

If you use the Key Vault Access policy approach, the following picture shows you the right settings:

![The Key Vault Access Policy for the Function App](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aibfydq5etvmhb1bo9zc.png)

## How the keys are stored
The Function App creates a secret for each keys you have in the host part (for example the master key) and for each key you create in each function inside the Function App.
For example, if you have the following keys:

![Two keys in your function in the Azure portal](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/98wj71utr5iijbipi8hw.png)

you have the following secret definitions in the Key Vault secrets page:

![The secret definitions for the function app keys in the portal](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/io1yktm9xobxhp6mlt3c.png)