An Azure function app runs every function under one identity, keeps its access keys in a storage account by default, and in the Node.js v4 programming model exposes HTTP triggers anonymously unless the developer sets an authorisation level. Those defaults explain most Functions-specific weaknesses: shared credentials across unrelated functions, a host storage account that doubles as a key store, and HTTP endpoints protected only by a key in a query string. This guide covers access key types and storage, the /admin endpoints and master key, managed identity and identity-based connections for AzureWebJobsStorage and bindings, RBAC, logging and a hardening baseline. It is written for cloud engineers, developers and security reviewers who own function apps. Platform-wide topics that Functions shares with web apps, such as Kudu, publishing credentials and built-in authentication, are covered in the Azure App Service Security Guide and are not repeated here.
Key takeaways
- Keys are shared secrets, not authentication. Microsoft states that access keys make endpoints harder to reach but that the only way to truly secure them is positive client authentication. Use Entra ID through App Service authentication or API Management for anything public.
- Check the default authLevel per language. HTTP triggers default to function level in most models, but the Node.js v4 model defaults to anonymous. Set authLevel explicitly on every trigger.
- The master key is an admin credential. _master unlocks the runtime APIs under /admin. Set functionsRuntimeAdminIsolationEnabled to true to switch those endpoints off and use the Azure Resource Manager API, which applies Azure RBAC, instead.
- Host storage is a key store. By default keys are stored in Blob storage in the AzureWebJobsStorage account. Anyone with data access to that account reaches the keys; move key storage to Key Vault and the host connection to managed identity.
- One app, one identity. Every function in an app shares the app's settings and managed identity. Microsoft recommends moving functions that do not need a credential into a separate function app.
How identity and access work in Azure Functions
A function app has three separate identity surfaces: callers of its HTTP endpoints, the app's own outbound identity, and the people and pipelines that manage it through Azure Resource Manager.
| Surface | Mechanism | What it protects | Main risk |
|---|---|---|---|
| Inbound HTTP callers | authLevel (anonymous, function, admin) with access keys in the code query parameter or x-functions-key header; optionally App Service authentication, API Management, access restrictions and private endpoints | Function endpoints | Anonymous triggers and keys distributed in client apps |
| Runtime admin APIs | Master key (_master) on /admin routes | Host status, test invocations, key management | Master key shared or leaked |
| Outbound access | System-assigned or user-assigned managed identity; identity-based connections for host storage and bindings; Key Vault references | Storage, Event Hubs, Service Bus, Key Vault and other services | Connection strings in app settings shared by all functions |
| Management plane | Azure RBAC on the function app (Owner, Contributor, Reader) | Settings, keys, code and identity | Contributor can read app settings and list keys |
Access key types
| Key type | Name | authLevel | Scope | Guidance |
|---|---|---|---|---|
| Function | default or user defined | function | One function endpoint | Preferred where keys are used: least privilege |
| Host | default or user defined | function | Every function endpoint in the app | Avoid handing to callers that need one function |
| Master | _master | admin | All functions plus runtime REST APIs under /admin | Microsoft: never share with third parties or put in native client apps |
| System | Set by the extension | n/a | Extension webhooks, for example the Event Grid trigger and Durable Task APIs | Treat as internal; rotate if exposed |
Microsoft documents that keys are random 32-byte values encoded as URL-safe base64, and that Functions-generated keys include signature and checksum components that identify them as Functions keys, which helps secret scanners recognise them. Let the platform generate keys rather than supplying your own values. Function keys take precedence over host keys with the same name.
Key lifecycle trap. Keys live in the app's secret store with their own lifecycle. Microsoft warns that deleting a function does not delete or rotate its keys, and because the storage location is derived from names, recreating a function with the same name reuses the old keys. Rotate keys explicitly when a function is retired or recreated.
Admin roles and privileged access
Functions supports the Azure built-in roles Owner, Contributor and Reader at the function app level. Microsoft notes that Contributor is required for most app-level tasks, that viewing Application Insights data also needs Monitoring Reader, and that only Owner can delete a function app.
| Capability | How it is exercised | Why it is privileged | Control |
|---|---|---|---|
| List host and function keys | ARM List Host Keys and List Function Keys APIs, portal App keys page, az functionapp keys list | Returns live secrets, including the system and master keys shown on the App keys page | Limit Contributor; alert on key listing outside pipelines |
| Read and write app settings | Configuration blade or ARM | Connection strings and secrets are visible to anyone who can list settings | Use Key Vault references and identity-based connections |
| Call /admin endpoints | Master key in x-functions-key | Runtime administration outside Azure RBAC | functionsRuntimeAdminIsolationEnabled set to true |
| Assign or change managed identity | Identity blade or ARM | Grants the code every role the identity holds | Restrict to platform team; review role assignments |
| Deploy code | Zip deploy, run from package, Flex Consumption deployment container | Code runs with the app's identity | Pipeline identity only; see the App Service guide for publishing credentials |
| Data access to the host storage account | Storage RBAC or account keys | Default key store and, on Flex Consumption, the default deployment package container | Separate owners; disable shared key access where supported |
- Disable the admin endpoints: functionsRuntimeAdminIsolationEnabled defaults to false, which allows /admin requests that present the master key. Setting it to true blocks /admin even with the master key. Microsoft notes it cannot be set for Linux apps on the Consumption plan, so plan hosting accordingly.
- Use custom roles for operators: people who need to restart apps or read logs do not need Contributor, which also reveals settings and keys. See the Azure RBAC and Service Principals Guide.
- Disable remote debugging except while actively debugging, as Microsoft advises.
Integrations, API tokens and service accounts
A function app is a non-human identity with several credentials: its managed identity, the host storage connection, binding connections, and any secrets in app settings.
Host storage with managed identity
Every function app needs a general-purpose storage account, set in AzureWebJobsStorage, which the runtime uses for key management, timer trigger management and Event Hubs checkpoints. Replace the connection string with an identity-based connection:
- Settings: AzureWebJobsStorage__accountName (or AzureWebJobsStorage__blobServiceUri, __queueServiceUri and __tableServiceUri for sovereign clouds and custom DNS), AzureWebJobsStorage__credential set to managedidentity, and AzureWebJobsStorage__clientId or __managedIdentityResourceId for a user-assigned identity. Without a client ID, the system-assigned identity is used.
- Roles: Microsoft gives Storage Blob Data Owner as the minimum for the host connection, plus Storage Table Data Contributor so diagnostic events can be written. Timer triggers and some bindings need further roles, listed per binding in Microsoft's connection documentation.
- Content share caveat: on Consumption and Elastic Premium plans, WEBSITE_CONTENTAZUREFILECONNECTIONSTRING still holds a connection string, because Azure Files does not support managed identity for the share. A Key Vault reference is possible but needs extra configuration on those plans. Flex Consumption avoids the file share: it runs code from a package in a blob container and lets you choose the deployment storage authentication method.
Bindings and secrets
- Identity-based binding connections: several binding extensions accept identity-based connections, with roles per binding (for example Azure Event Hubs Data Receiver for an Event Hubs trigger, Storage Queue Data Message Processor or Reader for a queue trigger). Assign the narrowest role on the specific resource, not the subscription.
- Key Vault references: where a secret is unavoidable, put a Key Vault reference in the app setting rather than the value, and grant the app's identity read access to that secret only. Use the Azure RBAC permission model on the vault: the Azure Key Vault Contributor Escalation 2024 showed that on vaults using the older access policy model, a role with Microsoft.KeyVault/vaults/write could grant itself access to every secret. See the Azure Key Vault Security Guide.
- Function key storage: AzureWebJobsSecretStorageType chooses where keys live: blob (default, in the AzureWebJobsStorage account, or a second account through an AzureWebJobsSecretStorageSas URL), keyvault (AzureWebJobsSecretStorageKeyVaultUri, with a managed identity), files (not recommended), kubernetes or containerapps. Prefer keyvault with a managed identity over an app registration secret.
- Organise by privilege: Microsoft points out that credentials in app settings give every function in the app the same access. Split functions that handle sensitive connections into their own app with their own identity.
- Validate trigger data: triggers and bindings do no validation. Treat queue, blob and event payloads as untrusted input, because a compromised upstream producer can feed your function. See the Azure Managed Identities Security Guide for how stolen identity tokens are used.
Logging and detection
Functions integrates with Application Insights for application telemetry and with Azure Monitor Logs through diagnostic settings for platform logs, which can be streamed to a Log Analytics workspace and connected to Microsoft Sentinel. Defender for Cloud assesses function app configuration, and Defender for App Service adds threat detection for apps on dedicated plans at extra cost.
| Signal | Source | Why it matters |
|---|---|---|
| Listing of host or function keys | Azure Activity Log | Key retrieval by a person or unexpected principal often precedes endpoint abuse |
| App settings or connection string changes | Activity Log | New secrets, changed storage accounts, AzureWebJobsSecretStorageType changes |
| Managed identity assignment or role assignment to the app's identity | Activity Log | Expands what the code can reach (persistence through additional cloud roles) |
| Site property change to functionsRuntimeAdminIsolationEnabled | Activity Log | Admin endpoints re-enabled |
| Requests to /admin routes | Application Insights requests, platform HTTP logs | Use of the master key |
| Spikes of 401 responses on HTTP triggers | Application Insights | Key guessing or a client using a rotated key |
| Data plane access to the host storage account's key container by principals other than the app | Storage diagnostic logs | Direct reading of stored keys |
| Token use by the app's managed identity from outside the platform | Entra sign-in logs for managed identities | Stolen identity token replayed elsewhere |
See the Azure Activity Log and Diagnostic Settings Guide for routing and retention, and the Microsoft Sentinel Guide for analytics rules.
Metrics that show it is working
- Anonymous triggers: HTTP-triggered functions with authLevel anonymous and no App Service authentication or APIM in front (target: only reviewed exceptions).
- Admin isolation: share of function apps with functionsRuntimeAdminIsolationEnabled true, where supported (target: 100 per cent).
- Secretless host storage: share of apps using identity-based AzureWebJobsStorage (target: rising to all eligible apps).
- Secrets in settings: app settings holding literal connection strings or keys rather than Key Vault references (target: zero outside the documented content share exception).
- Key age: days since host and function keys were last rotated, against your rotation standard.
Hardening baseline
- Inventory: list every function app with plan, runtime and programming model, managed identity, authLevel of each HTTP trigger, key storage type and host storage connection type.
- Set authLevel explicitly on every HTTP trigger, paying attention to Node.js v4 apps. Remember that authorisation is disabled when running locally, so test levels after publishing to a non-production app.
- Put real authentication in front: App Service authentication with Entra ID for user-facing or service callers, or API Management with access restrictions that accept traffic only from the APIM instance. Keep function keys as a secondary control.
- Require HTTPS and the latest TLS version, restrict CORS to named origins with no wildcards, and add access restrictions or private endpoints. Microsoft notes that with no access restriction rules an app accepts traffic from any address.
- Isolate the admin endpoints with functionsRuntimeAdminIsolationEnabled, then remove any process that relied on the master key.
- Move key storage to Key Vault with AzureWebJobsSecretStorageType keyvault and a managed identity. Pilot on one app, confirm that callers still authenticate after the change, and rotate keys after the move. Roll back by restoring the previous setting value.
- Switch host storage to managed identity with the AzureWebJobsStorage__ settings and the documented roles. Test in a staging slot or a copy of the app first; a wrong role stops the host from starting. Roll back by restoring the connection string setting.
- Replace remaining secrets with identity-based binding connections or Key Vault references, and split functions by privilege.
- Secure dependencies: lock down the host storage account and Application Insights resource with network rules and RBAC, as Microsoft advises, and set a daily usage quota on Consumption apps to cap runaway or abusive execution.
Framework mapping
| Control area | NIST SP 800-53 Rev 5 | NIST CSF 2.0 | ATT&CK |
|---|---|---|---|
| Endpoint authentication and authLevel | IA-9, AC-3 | PR.AA-03 | T1190 Exploit Public-Facing Application |
| Access keys and master key | IA-5 | PR.AA-01 | T1552.001 Credentials In Files |
| Managed identity and least privilege | AC-6 | PR.AA-05 | T1098.003 Additional Cloud Roles |
| Secrets in Key Vault, encrypted storage | SC-12, SC-28 | PR.DS-01 | T1555.006 Cloud Secrets Management Stores |
| Activity Log, diagnostic settings, Sentinel | AU-2, AU-6 | DE.CM-09 | T1078.004 Cloud Accounts |
In ISO/IEC 27001:2022 terms the work maps to A.8.5 Secure authentication, A.8.2 Privileged access rights, A.8.24 Use of cryptography and A.8.15 Logging. Microsoft also publishes an Azure security baseline for Azure Functions aligned to the Microsoft cloud security benchmark.
Common misconfigurations
- Anonymous by accident: Node.js v4 HTTP triggers deployed without authLevel, exposing the endpoint publicly with no key.
- Master key in clients: the _master or a host key embedded in a mobile app, SPA or partner integration, giving every function and the admin API to anyone who extracts it.
- Keys that outlive functions: a function deleted and recreated with the same name, silently reusing keys that were shared with a former partner.
- Host storage as a soft target: AzureWebJobsStorage on a connection string with shared key access, so any leak of that string exposes stored keys, timer state and, on Flex Consumption, the deployment package.
- One app for everything: a payments function and a public health-check function in the same app, sharing a database connection string and identity.
- Wildcard CORS and no access restrictions: endpoints callable from any origin and any address, relying only on keys.
Practitioner checklist
- Set authLevel explicitly on every HTTP trigger and review all anonymous ones.
- Front public functions with App Service authentication or API Management.
- Set functionsRuntimeAdminIsolationEnabled to true where supported.
- Move key storage to Key Vault and rotate keys after functions are retired or recreated.
- Switch AzureWebJobsStorage to an identity-based connection with Storage Blob Data Owner and Storage Table Data Contributor.
- Replace connection strings with identity-based binding connections or Key Vault references.
- Split functions with sensitive access into separate apps with their own identities.
- Restrict CORS, require HTTPS and current TLS, and add access restrictions or private endpoints.
- Alert on key listing, settings changes and identity role assignments in the Activity Log.
- Limit Contributor on function apps and use custom roles for operators.
Standards and references
- Microsoft: Securing Azure Functions
- Microsoft: Work with access keys in Azure Functions
- Microsoft: App settings reference for Azure Functions
- Microsoft: Manage connections in Azure Functions
- Microsoft: Azure Functions HTTP trigger
- Microsoft: Azure Functions Flex Consumption plan hosting
- Microsoft: Azure Functions developer guide
Related NHI Mgmt Group resources: Serverless Security Guide · Azure App Service Security Guide · Azure Managed Identities Security Guide · Azure Key Vault Security Guide · Azure RBAC and Service Principals Guide