This sample demonstrates how to retrieve secrets programmatically from Azure Key vault in Azure Functions, implemented using azure-functions-java-library. The secret is cached in-memory.
The function is invoked with an HTTP trigger.
- Java 8
- Gradle
- Azure CLI
For this sample we have to create a keyvault and give access to it to the local developer and the system managed identity of the deployed function. This way we can develop and debug locally, as well as running in azure.
az login
KEYVAULT=simon-testar-keyvault
RESOURCEGROUP=simon-testar
az group create --name "${RESOURCEGROUP}" --location eastus
az keyvault create --name "${KEYVAULT}" --resource-group "${RESOURCEGROUP}" --location westeurope
Grant permissions to a specific developer to access the keyvault:
az keyvault set-policy --name "${KEYVAULT}" --upn [email protected] --secret-permissions get
Or better, grant permissions to security group:
az keyvault set-policy --name "${KEYVAULT}" --object-id deadbeef-cafe-f00d-a184-540cb8e8b93b --secret-permissions get
az keyvault secret set --vault-name "${KEYVAULT}" --name "asecret" --value "hush-hush"
Start the function host locally:
gradle azureFunctionsRun
In a different terminal, try it out:
curl -w "\n" https://localhost:7071/api/HttpExample
You should get something like:
Hello, hush-hush
If you change the secret, the change should be reflected after the cached value expires.
In this example we use a standalone in-memory cache (https://cache2k.org) configured to do a read through (if there is a cache miss, the value is loaded into the cache and then returned).
Secrets are normally seldom changing, so to reduce the number of calls to Keyvault, the value can be cached for a short while (to the order of minutes). This means that there has to be some kind of handling for the case that the old secret is returned (and not working when used).
This will not actually work, pending the resolution of this bug: https://github.com/Azure/Azure-Functions/issues/1533
gradle azureFunctionsDeploy
Create system assigned identity:
az functionapp identity assign --name simon-testar-keyvault-2 --resource-group "${RESOURCEGROUP}"
You get a response like this one:
{
"principalId": "0d15ea5e-cafe-f00d-beef-defec8eddead",
"tenantId": "deadfa11-04d4-4e86-875f-e48fa80b9529",
"type": "SystemAssigned",
"userAssignedIdentities": null
}
On Key vault, configure accesspolicy to read secrets for id of function.
az keyvault set-policy --name "${KEYVAULT}" --object-id "0d15ea5e-cafe-f00d-beef-defec8eddead" --secret-permissions get