Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
In many ways, planning for secure development, deployment, and operation of serverless functions is much the same as for any web-based or cloud-hosted application. Azure App Service provides the hosting infrastructure for your function apps. This article provides security strategies for running your function code, and how App Service can help you secure your functions.
The platform components of Azure App Service, including Azure virtual machines (VMs), storage, network connections, web frameworks, and management and integration features are actively secured and hardened. App Service goes through vigorous compliance checks on a continuous basis to make sure that:
- Your app resources are secured from other customers' Azure resources.
- VM instances and runtime software are regularly updated to address newly discovered vulnerabilities.
- Communication of secrets (such as connection strings) between your app and other Azure resources (such as Azure SQL Database) stays within Azure and doesn't cross any network boundaries. Secrets are always encrypted when stored.
- All communication over the App Service connectivity features, such as hybrid connection, is encrypted.
- Connections with remote management tools like Azure PowerShell, the Azure CLI, Azure SDKs, and REST APIs, are all encrypted.
- 24-hour threat management protects the infrastructure and platform against malware, distributed denial-of-service (DDoS), man-in-the-middle attacks, and other threats.
For more information on infrastructure and platform security in Azure, see the Azure Trust Center.
For a set of security recommendations that follow the Microsoft cloud security benchmark, see Azure Security Baseline for Azure Functions.
Secure operation
This section guides you on configuring and running your function app as securely as possible.
Defender for Cloud
Defender for Cloud integrates with your function app in the portal. It provides, for free, a quick assessment of potential configuration-related security vulnerabilities. Function apps running in a dedicated plan can also use Defender for Cloud's enhanced security features for an extra cost. For more information, see Defender for App Service.
Log and monitor
One way to detect attacks is through activity monitoring and logging analytics. Functions integrates with Application Insights to collect log, performance, and error data for your function app. Application Insights automatically detects performance anomalies and includes powerful analytics tools to help you diagnose issues and understand how your functions are used. For more information, see Monitor Azure Functions.
Functions also integrates with Azure Monitor Logs to enable you to consolidate function app logs with system events for easier analysis. You can use diagnostic settings to configure the streaming export of platform logs and metrics for your functions to the destination of your choice, such as a Logs Analytics workspace. For more information, see Monitoring Azure Functions with Azure Monitor Logs.
For enterprise-level threat detection and response automation, stream your logs and events to a Logs Analytics workspace. You can then connect Microsoft Sentinel to this workspace. For more information, see What is Microsoft Sentinel.
For more security recommendations for observability, see the Azure security baseline for Azure Functions.
Secure HTTP endpoints
HTTP endpoints that are exposed publicly provide a vector of attack for malicious actors. When securing your HTTP endpoints, you should use a layered security approach. These techniques can be used to reduce the vulnerability of publicly exposed HTTP endpoints, ordered from most basic to most secure and restrictive:
- Require HTTPS
- Require access keys
- Enable App Service Authentication/Authorization
- Use Azure API Management (APIM) to authenticate requests
- Deploy your function app to a virtual network
- Deploy your function app in isolation
Require HTTPS
By default, clients can connect to function endpoints by using either HTTP or HTTPS. You should redirect HTTP to HTTPS because HTTPS uses the TLS protocol to provide a secure connection, which is both encrypted and authenticated. To learn how, see Enforce HTTPS.
When you require HTTPS, you should also require the latest TLS version. To learn how, see Enforce TLS versions.
For more information, see Secure connections (TLS).
Function access keys
Functions lets you use keys to make it harder to access your function endpoints. Unless the HTTP access level on an HTTP triggered function is set to anonymous
, requests must include an access key in the request. For more information, see Work with access keys in Azure Functions.
While access keys can provide some mitigation for unwanted access, the only way to truly secure your function endpoints is by implementing positive authentication of clients accessing your functions. You can then make authorization decisions based on identity.
For the highest level of security, you can also secure the entire application architecture inside a virtual network using private endpoints or by running in isolation..
Disable administrative endpoints
Function apps can serve administrative endpoints under the /admin
route that can be used for operations such as obtaining host status information and performing test invocations. When exposed, requests against these endpoints must include the app's master key. Administrative operations are also available through the Azure Resource Manager Microsoft.Web/sites
API, which offers Azure RBAC. You can disable the /admin
endpoints by setting the functionsRuntimeAdminIsolationEnabled
site property to true
. This property can't be set for apps running on the Linux Consumption SKU, and it can't be set for apps running on version 1.x of Azure Functions. If you're using version 1.x, you must first migrate to version 4.x.
Enable App Service Authentication/Authorization
The App Service platform lets you use Microsoft Entra ID and several non-Microsoft identity providers to authenticate clients. You can use this strategy to implement custom authorization rules for your functions, and you can work with user information from your function code. For more information, see Authentication and authorization in Azure App Service and Working with client identities.
Use Azure API Management (APIM) to authenticate requests
APIM provides various API security options for incoming requests. For more information, see API Management authentication policies. With APIM in place, you can configure your function app to accept requests only from the IP address of your APIM instance. For more information, see IP address restrictions.
Permissions
As with any application or service, the goal is to run your function app with the lowest possible permissions.
User management permissions
Functions supports built-in Azure role-based access control (Azure RBAC). Azure roles supported by Functions are Contributor, Owner, and Reader.
Permissions are effective at the function app level. The Contributor role is required to perform most function app-level tasks. You also need the Contributor role along with the Monitoring Reader permission to be able to view log data in Application Insights. Only the Owner role can delete a function app.
Organize functions by privilege
Connection strings and other credentials stored in application settings give all of the functions in the function app the same set of permissions in the associated resource. Consider minimizing the number of functions with access to specific credentials by moving functions that don't use those credentials to a separate function app. You can always use techniques such as function chaining to pass data between functions in different function apps.
Managed identities
A managed identity from Microsoft Entra ID allows your app to easily access other Microsoft Entra-protected resources, such as Azure Key Vault. The Azure platform manages the identity, so you don't need to provision or rotate any secrets. For more information about managed identities in Microsoft Entra ID, see Managed identities for Azure resources.
You can grant two types of identities to your application:
- A system-assigned identity is tied to the app and is deleted if the app is deleted. An app can have only one system-assigned identity.
- A user-assigned identity is a standalone Azure resource that can be assigned to your app. An app can have multiple user-assigned identities. One user-assigned identity can be assigned to multiple Azure resources, such as two App Service apps.
Managed identities can be used in place of secrets for connections from some triggers and bindings. See Identity-based connections.
For more information, see Use managed identities for App Service and Azure Functions.
Restrict CORS access
Cross-origin resource sharing (CORS) is a way to allow web apps running in another ___domain to make requests to your HTTP trigger endpoints. App Service provides built-in support for handing the required CORS headers in HTTP requests. CORS rules are defined on a function app level.
It's tempting to use a wildcard that allows all sites to access your endpoint. This approach defeats the purpose of CORS, which is to help prevent cross-site scripting attacks. Instead, add a separate CORS entry for the ___domain of each web app that must access your endpoint.
Managing secrets
To be able to connect to the various services and resources needed to run your code, function apps need to be able to access secrets, such as connection strings and service keys. This section describes how to store secrets required by your functions.
Never store secrets in your function code.
Application settings
By default, you store connection strings and secrets used by your function app and bindings as application settings. This approach makes these credentials available to both your function code and the various bindings used by the function. The application setting (key) name is used to retrieve the actual value, which is the secret.
For example, every function app requires an associated storage account, which is used by the runtime. By default, the connection to this storage account is stored in an application setting named AzureWebJobsStorage
.
App settings and connection strings are stored encrypted in Azure. They're decrypted only before being injected into your app's process memory when the app starts. The encryption keys are rotated regularly. If you prefer to manage the secure storage of your secrets, the app settings should instead be references to Azure Key Vault secrets.
You can also encrypt settings by default in the local.settings.json
file when developing functions on your local computer. For more information, see Encrypt the local settings file.
Key Vault references
While application settings are sufficient for most functions, you might want to share the same secrets across multiple services. In this case, redundant storage of secrets results in more potential vulnerabilities. A more secure approach is to use a central secret storage service and use references to this service instead of the secrets themselves.
Azure Key Vault is a service that provides centralized secrets management, with full control over access policies and audit history. You can use a Key Vault reference in the place of a connection string or key in your application settings. For more information, see Use Key Vault references for App Service and Azure Functions.
Identity-based connections
Identities might be used in place of secrets for connecting to some resources. Approach has the advantage of not requiring the management of a secret, and it provides more fine-grained access control and auditing.
When you write code that creates the connection to Azure services that support Microsoft Entra authentication, you can use an identity instead of a secret or connection string. Details for both connection methods are covered in the documentation for each service.
Some Azure Functions binding extensions can be configured to access services using identity-based connections. For more information, see Configure an identity-based connection.
Set usage quotas
Consider setting a usage quota for functions running in a Consumption plan. When you set a daily GB-sec limit on the total execution of functions in your function app, execution is stopped when the limit is reached. This approach could potentially help mitigate against malicious code executing your functions. To learn how to estimate consumption for your functions, see Estimating Consumption plan costs.
Data validation
The triggers and bindings used by your functions don't provide any extra data validation. Your code must validate any data received from a trigger or input binding. If an upstream service is compromised, you don't want unvalidated inputs flowing through your functions. For example, if your function stores data from an Azure Storage queue in a relational database, you must validate the data and parameterize your commands to avoid SQL injection attacks.
Don't assume that the data coming into your function has already been validated or sanitized. It's also a good idea to verify that the data being written to output bindings is valid.
Handle errors
While it seems basic, it's important to write good error handling in your functions. Unhandled errors bubble up to the host and the runtime handles these errors. Different bindings handle the processing of errors differently. For more information, see Azure Functions error handling.
Disable remote debugging
Make sure that remote debugging is disabled, except when you're actively debugging your functions. You can disable remote debugging in the General Settings tab of your function app Configuration in the portal.
Restrict CORS access
Azure Functions supports cross-origin resource sharing (CORS). CORS is configured in the portal and through the Azure CLI. The CORS allowed origins list applies at the function app level. With CORS enabled, responses include the Access-Control-Allow-Origin
header. For more information, see Cross-origin resource sharing.
Don't use wildcards in your allowed origins list. Instead, list the specific domains from which you expect to get requests.
Store data encrypted
Azure Storage encrypts all data in a storage account at rest. For more information, see Azure Storage encryption for data at rest.
By default, data is encrypted with Microsoft-managed keys. For more control over encryption keys, you can supply customer-managed keys to use for encryption of blob and file data. These keys must be present in Azure Key Vault for Functions to be able to access the storage account. To learn more, see Encrypt your application data at rest using customer-managed keys.
Secure related resources
A function app frequently depends on other resources, so part of securing the app is securing these external resources. At a minimum, most function apps include a dependency on Application Insights and Azure Storage. Consult the Azure security baseline for Azure Monitor and the Azure security baseline for Storage for guidance on securing these resources.
Important
The storage account is used to store important app data, sometimes including the application code itself. You should limit access from other apps and users to the storage account.
You should also consult the guidance for any resource types your application logic depends on, both as triggers and bindings and from your function code.
Secure deployment
Azure Functions tooling integration makes it easy to publish local function project code to Azure. It's important to understand how deployment works when considering security for an Azure Functions topology.
Deployment credentials
App Service deployments require a set of deployment credentials. These deployment credentials are used to secure your function app deployments. The App Service platform manages deployment credentials. Credentials are encrypted at rest.
There are two kinds of deployment credentials:
User-level credentials: One set of credentials for the entire Azure account. These credentials can be used to deploy to App Service for any app in any subscription that the Azure account has permission to access. This credentials set is the default that surfaces in the portal's graphical environment, like in Overview and Properties on the app's resource pane. When a user is granted app access via role-based access control (RBAC) or coadministrator permissions, they can use their user-level credentials until access is revoked. Don't share these credentials with other Azure users.
App-level credentials: One set of credentials for each app. These credentials can be used to deploy to that app only. The credentials for each app are generated automatically at app creation. They can't be configured manually, but can be reset anytime. To grant a user access to app-level credentials via RBAC, that user must have Contributor level or higher permissions on the app (including the built-in Website Contributor role). Readers aren't allowed to publish, and can't access those credentials.
At this time, Key Vault isn't supported for deployment credentials. To learn more about managing deployment credentials, see Configure deployment credentials for Azure App Service.
Disable FTP
By default, each function app has an FTP endpoint enabled. The FTP endpoint is accessed using deployment credentials.
FTP isn't recommended for deploying your function code. FTP deployments are manual, and they require you to synchronize triggers. For more information, see FTP deployment.
When you're not planning on using FTP, you should disable it in the portal. If you do choose to use FTP, you should enforce FTPS.
Secure the scm
endpoint
Every function app has a corresponding scm
service endpoint that is used by the Advanced Tools (Kudu) service for deployments and other App Service site extensions. The scm
endpoint for a function app is always a URL in the form https://<FUNCTION_APP_NAME>.scm.azurewebsites.net
. When you use network isolation to secure your functions, you must also account for this endpoint.
By having a separate scm
endpoint, you can control deployments and other Advanced Tools functionalities for function apps that are isolated or running in a virtual network. The scm
endpoint supports both basic authentication (using deployment credentials) and single sign-on with your Azure portal credentials. For more information, see Accessing the Kudu service.
Continuous security validation
Since security needs to be considered at every step in the development process, it makes sense to also implement security validations in a continuous deployment environment. This approach is sometimes called DevSecOps. Using Azure DevOps for your deployment pipeline lets you integrate validation into the deployment process. For more information, see Secure your Azure Pipelines.
Network security
Restricting network access to your function app lets you control who can access your functions endpoints. Functions uses App Service infrastructure to enable your functions to access resources without using internet-routable addresses or to restrict internet access to a function endpoint. To learn more about these networking options, see Azure Functions networking options.
Set access restrictions
Access restrictions allow you to define lists of allow/deny rules to control traffic to your app. Rules are evaluated in priority order. If no rules are defined, your app accepts traffic from any address. For more information, see Azure App Service access restrictions.
Secure the storage account
When you create a function app, you must create or link to a general-purpose Azure Storage account that supports Blob, Queue, and Table storage. You can replace this storage account with one that is secured by a virtual network with access enabled by service endpoints or private endpoints. For more information, see Restrict your storage account to a virtual network.
Deploy your function app to a virtual network
Azure Private Endpoint is a network interface that connects you privately and securely to a service powered by Azure Private Link. Private Endpoint uses a private IP address from your virtual network, effectively bringing the service into your virtual network.
You can use Private Endpoint for your functions hosted in the Flex Consumption, Elastic Premium, and Dedicated (App Service) plans.
If you want to make calls to Private Endpoints, then you must make sure that your DNS lookups resolve to the private endpoint. You can enforce this behavior in one of the following ways:
- Integrate with Azure DNS private zones. When your virtual network doesn't have a custom DNS server, this is done automatically.
- Manage the private endpoint in the DNS server used by your app. To manage a private endpoint, you must know the endpoint address and use an A record to reference the endpoint you're trying to reach.
- Configure your own DNS server to forward to Azure DNS private zones.
To learn more, see using Private Endpoints for Web Apps.
Deploy your function app in isolation
Azure App Service Environment provides a dedicated hosting environment in which to run your functions. These environments let you configure a single front-end gateway that you can use to authenticate all incoming requests. For more information, see Integrate your ILB App Service Environment with the Azure Application Gateway.
Use a gateway service
Gateway services, such as Azure Application Gateway and Azure Front Door let you set up a Web Application Firewall (WAF). WAF rules are used to monitor or block detected attacks, which provide an extra layer of protection for your functions. To set up a WAF, your function app needs to be running in an ASE or using Private Endpoints (preview). For more information, see Using private endpoints.