This article shows how to secure Azure Functions using API Keys. This is useful, if you have no control over the API client implementation, the client code base cannot be easily changed or the client is not Azure hosted. This should only be used with trusted clients and is for machine to machine usage.
Code: https://github.com/damienbod/AzureFunctionsSecurity
Blogs in the series
- Securing Azure Functions using API Keys
- Securing Azure Functions using Certificate authentication
- Securing Azure Functions using an Azure Virtual Network
- Securing Azure Key Vault inside a VNET and using from an Azure Function
- Securing Azure Functions using Azure AD JWT Bearer token authentication for user access tokens
Azure Functions AuthorizationLevel.Anonymous
When setting up new Azure Functions, the trigger used can set the AuthorizationLevel enum of the Function. If using Anonymous, no security is required. No API Key is required for this.
[FunctionName("RandomStringAuthLevelAnonymous")] public IActionResult RandomStringAuthLevelAnonymous( [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req) { return new OkObjectResult(GetEncodedRandomString()); }
API Keys Azure Functions AuthorizationLevel.Function
The AuthorizationLevel.Function can be set on the Azure Function to require an API Key. By setting the enum to Function, you ensure that a deployed instance of the functions will required at least a Function Key to access the resource behind the API. A Host API Key will also grant access to this level of authorization.
[FunctionName("RandomStringAuthLevelFunc")] public IActionResult RandomStringAuthLevelFunc( [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req) { return new OkObjectResult(GetEncodedRandomString()); }
The API Key can be set in the Azure portal. Open the functions in the portal, select the Functions blade and select the Function which requires an API key.
Add a new Function Key using the Function Keys blade.
Using Postman, the Function with the API Key can be tested. If a HTTP request is sent to the API, a 401 is returned. By adding the x-functions-key header with the API key value, the data will be returned. You should only send API keys using HTTP headers and not in the URL as a parameter. The HTTP URL parameters are encypted in a HTTPS request, but usually get logged. The logs tend to have a lower level of access than the secrets. A Host Key can also be used to access an AuthorizationLevel.Function API.
API Keys Azure Functions AuthorizationLevel.Admin
The AuthorizationLevel.Admin authorization can be set, if you require only a single API Key for all the functions in the deployment, or some clients have admin access to all the Functions. This cannot be set for each function.
[FunctionName("RandomStringAuthLevelAdmin")] public IActionResult RandomStringAuthLevelAdmin( [HttpTrigger(AuthorizationLevel.Admin, "get", Route = null)] HttpRequest req) { return new OkObjectResult(GetEncodedRandomString()); }
A key which can be used for the AuthorizationLevel.Admin can be set in the Azure portal using the Host Keys.
Notes:
The API key is shared between both applications which is one of the problems with this security architecture. Shared secrets seem to get shared a lot or are made public be accident.
Links:
https://docs.microsoft.com/en-us/azure/azure-functions/security-concepts
https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-http-webhook-trigger
[…] Securing Azure Functions using API Keys (Damien Bowden) […]
[…] Securing Azure Functions using API Keys […]