The Azure Functions Runtime exposes a management API that enables users to programmatically add, delete, or update function keys. In this article, I will show you how to use this API to manage Azure Functions Keys using PowerShell.
Authorization keys
With Azure Functions, you can use keys to prevent anonymous users to access your HTTP endpoints. The Requests then must include an API key (either a function or host key) which can be included in two ways:
Providing the key
Using an URL query string named code
https://<FUNCTION_APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>?code=<API_KEY>
Using an HTTP header named x-functions-key
Invoke-WebRequest ` -Uri 'https://<FUNCTION_APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>' ` -Headers @{'x-functions-key' = '<API_KEY>'}
Authorization scopes
Keys can be specified on three levels:
Function Keys
The keys defined on a function-level allow access only to a single function.
Host Keys
A Host Key allows access to all functions within a function app.
The Master key (named _master
) not only allows host-level access to all functions within a function app but also provides access to the Azure Function Runtime REST APIs.
Note: This Key cannot be revoked thus you should avoid sharing this key.
You can find more information about Authorization Keys here.
Key management API
The Key management API allows us to programmatically add, delete, or update our Azure Functions keys. In order to use this API, we need to get an access token beforehand. We can obtain the token using the following PowerShell script.
Obtain an access token using PowerShell
param ( [Parameter(Mandatory = $true)] [string] $ResourceGroupName, [Parameter(Mandatory = $true)] [string] $FunctionAppName ) $publishingCredentials = Invoke-AzResourceAction ` -ResourceGroupName $ResourceGroupName ` -ResourceType 'Microsoft.Web/sites/config' ` -ResourceName ('{0}/publishingcredentials' -f $FunctionAppName) ` -Action list ` -ApiVersion 2019-08-01 ` -Force $base64Credentials = [Convert]::ToBase64String( [Text.Encoding]::ASCII.GetBytes( ('{0}:{1}' -f $publishingCredentials.Properties.PublishingUserName, $publishingCredentials.Properties.PublishingPassword) ) ) Invoke-RestMethod ` -Uri ('https://{0}.scm.azurewebsites.net/api/functions/admin/token' -f $FunctionAppName) ` -Headers @{ Authorization = ('Basic {0}' -f $base64Credentials) }
This script is also available on GitHub.
Before we can invoke this function, we have to log in to Azure using the Login-AzAccount
cmdlet. Then all we have to do is to pass the name of the resource group and the name of the Azure Function App:
Login-AzAccount $jwtToken = ./Get-AzureFunctionsAccessToken.ps1 ` -ResourceGroupName '<RESOURCE_GROUP_NAME>' ` -FunctionAppName '<FUNCTION_APP_NAME>'
Now we can use the return value (access token) to perform requests against the Key management API. Here a few examples:
Key Management API examples
Create a new host key with an auto-generated value (POST)
This is how the host key POST interface looks like:
POST https://<FUNCTION_APP_NAME>.azurewebsites.net/admin/functions/host/keys/<KEY_NAME>
Now let’s add a new host key named mynewkey
to my Azure Function mbr-pwsh-test
using PowerShell and the token ($jwtToken
) that we retrieved previously:
Invoke-RestMethod ` -Uri 'https://mbr-pwsh-test.azurewebsites.net/admin/host/keys/mynewkey' ` -Headers @{Authorization = ("Bearer {0}" -f $jwtToken) } ` -Method Post
This is how it looks like in the Portal:
Update a host key with a predefined value (PUT)
This is how the host key PUT interface looks like:
PUT https://<FUNCTION_APP_NAME>.azurewebsites.net/admin/functions/host/keys/<KEY_NAME> { "name": "keyname", "value" : "keyvalue" }
Now let’s update our previous created key with a new value. You can use the same endpoint to create a new key with a predefined value (instead of the auto-generated value that is used by the POST endpoint)
$keyName = 'mynewkey' $keyValue = 'my-secret-value' Invoke-RestMethod ` -Uri "https://mbr-pwsh-test.azurewebsites.net/admin/host/keys/$keyName"` -Headers @{Authorization = ("Bearer {0}" -f $jwtToken) } ` -Body ( @{ 'name' = $keyName; 'value' = $keyValue } | ConvertTo-Json) ` -ContentType 'application/json' ` -Method PUT
We can see the updated key inside the Azure Portal:
Retrieve all host keys (GET)
The request to retrieve all host keys look like this:
GET https://<FUNCTION_APP_NAME>.azurewebsites.net/admin/functions/host/keys
Let’s retrieve them using PowerShell.
Note: I piped the result to the Select-Object cmdlet to get a cleaner output on the console.
Invoke-RestMethod ` -Uri 'https://mbr-pwsh-test.azurewebsites.net/admin/host/keys/mynewkey' ` -Headers @{Authorization = ("Bearer {0}" -f $jwtToken) } ` -Method GET | Select-Object -ExpandProperty keys
And here is the output:
Retrieve a specific host key (GET)
To retrieve a specific host key, we just have to add the name of the key to the URL:
GET https://<FUNCTION_APP_NAME>.azurewebsites.net/admin/functions/host/keys/<KEY_NAME>
Again, let’s do this using PowerShell:
Invoke-RestMethod ` -Uri 'https://mbr-pwsh-test.azurewebsites.net/admin/host/keys/mynewkey' ` -Headers @{Authorization = ("Bearer {0}" -f $jwtToken) } ` -Method GET
Here is our key:
Remove a host key (DELETE)
The host key DELETE endpoint uses the same URL like the POST endpoint:
DELETE https://<FUNCTION_APP_NAME>.azurewebsites.net/admin/functions/host/keys/<KEY_NAME>
We can delete our mynewkey
host key using the following PowerShell script:
Invoke-RestMethod ` -Uri 'https://mbr-pwsh-test.azurewebsites.net/admin/host/keys/mynewkey' ` -Headers @{Authorization = ("Bearer {0}" -f $jwtToken) } ` -Method DELETE
Convenience script to set multiple host keys
In addition to the examples, I want to share a script with you where you can set multiple host keys with either a predefined or auto-generated value:
param ( [Parameter(Mandatory = $true)] [string] $ResourceGroupName, [Parameter(Mandatory = $true)] [string] $FunctionAppName, [Parameter(Mandatory = $true)] [hashtable] $FunctionKeys ) $functionBaseUrl = 'https://{0}.azurewebsites.net' -f $FunctionAppName $publishingCredentials = Invoke-AzResourceAction ` -ResourceGroupName $ResourceGroupName ` -ResourceType 'Microsoft.Web/sites/config' ` -ResourceName ('{0}/publishingcredentials' -f $FunctionAppName) ` -Action list ` -ApiVersion 2019-08-01 ` -Force $base64Credentials = [Convert]::ToBase64String( [Text.Encoding]::ASCII.GetBytes( ('{0}:{1}' -f $publishingCredentials.Properties.PublishingUserName, $publishingCredentials.Properties.PublishingPassword) ) ) $jwtToken = Invoke-RestMethod ` -Uri ('https://{0}.scm.azurewebsites.net/api/functions/admin/token' -f $FunctionAppName) ` -Headers @{ Authorization = ('Basic {0}' -f $base64Credentials) } $FunctionKeys.Keys | ForEach-Object { if ($FunctionKeys[$_]) { Invoke-RestMethod ` -Uri ('{0}/admin/host/keys/{1}' -f $functionBaseUrl, $_) ` -Headers @{Authorization = ("Bearer {0}" -f $jwtToken) } ` -Method Put ` -Body ( @{ 'name' = $_; 'value' = $FunctionKeys[$_] } | ConvertTo-Json) ` -ContentType 'application/json' } else { Invoke-RestMethod ` -Uri ('{0}/admin/host/keys/{1}' -f $functionBaseUrl, $_) ` -Headers @{Authorization = ("Bearer {0}" -f $jwtToken) } ` -Method Post } }
In here the example of how to call the script to create two keys:
Login-AzAccount ./Add-AzureFunctionHostKey.ps1 ` -ResourceGroupName "apim-rg" ` -FunctionAppName "mbr-pwsh-test" ` -FunctionKeys @{ myKey1 = 'myValue1' # predefined key mykey2 = $null # key with auto-generated value }
The script is also available on GitHub.
Manage keys on function-level
Now we know how to manage (add, update, get, delete) an Azure Function Host Key using the Key management API. Of course, we can also manage a Function Key by changing the URL from admin/functions/host
to admin/function/<FUNCTION_NAME>
. You can find more information about the API here.