In Azure, securing the connections between Storage Accounts and a Function App is crucial. These connections are used to store source code and secrets, among other things. But they can also become a point of vulnerability if they rely on Shared Access Keys.
In this article, we will explore the different connections between a Function App and its Storage Account(s). Then, we’ll see how to secure them using Managed Identities and Azure Key Vault to improve the security posture of your Azure environment.
When creating a new Function App, two types of connections may exist with a Storage Account. They appear in the Function App’s environment variables:
The first connection to a Storage Account is Azure Web Jobs Storage. In this Storage Account, the Function App creates two blob containers:
This Storage Account is mandatory. The data stored here is essential for the Function App to work properly, and a failure at this level will completely prevent the Function App from running.
You can find the documentation for this App Setting here.
This connection, although it can point to the same Storage Account, is different. It provides access to the Azure File Storage of a Storage Account. In this file share, the Function App stores the application’s source code. This code is used during scale-out operations to redeploy the function.
This configuration is mandatory for consumption-based Function Apps that are not using Run-From-Package or Docker containers. Documentation can be found here.
Currently, as shown in the environment variables, Storage Accounts are linked to Function Apps using a Shared Access Key. As the name suggests, this is a shared key visible in the Function App settings. It grants access to the Storage Account with varying levels of permissions.
This approach has several drawbacks:
The best practice to secure links between Storage Accounts and Function Apps is to replace Shared Access Keys with Managed Identities. This method allows one Azure component to access another using an identity in Microsoft Entra ID.
This identity can be:
Managed Identities allow secure connections between Azure components without handling access keys or secrets.
To configure your Function App to connect to the Azure Web Jobs Storage via a Managed Identity, follow these steps:
Replace the AzureWebJobsStorage
App Setting with the following three settings:
AzureWebJobsStorage_accountName
→ the name of the Storage AccountAzureWebJobsStorage_clientId
→ the client ID of the Managed IdentityAzureWebJobsStorage_credential
→ set to "managedIdentity"
Now your Function App is configured to use its Managed Identity to connect securely to the Storage Account.
Finally, you can disable access via Shared Access Keys in the Storage Account for greater security (be cautious of side effects).
The WEBSITE_CONTENTAZUREFILECONNECTIONSTRING
setting differs from the previous one: it stores a connection string to Azure File Storage, not Blob Storage. Currently, Azure File Storage does not support Managed Identities.
To secure this connection, you should:
Keep the Shared Access Key, but store it in Azure Key Vault:
Configure the Function App to reference the value from Key Vault using its Managed Identity.
@Microsoft.Keyvault(SecretUri={LeLienDuKeyvault}/secrets/{leNomDuSecret})
Also, add a parameter to tell the Function App not to validate the value at deployment time, since the secret will only be retrieved from Key Vault at runtime.
Before deployment, make sure an Azure File Storage container already exists in the Storage Account. Its name must match the WEBSITE_CONTENTSHARE
parameter.
For example, create an empty container named demo-articleblob-ddebab0e
. This is mandatory because the Function App cannot create an empty container itself when validation of WEBSITE_CONTENTSHARE
is skipped.
You can integrate this steps into your deployment solution (ARM template, Bicep, Terraform, etc.).
Once completed, the Function App works without storing Shared Access Keys in its settings. Instead, it retrieves the Storage Account connection string from Azure Key Vault via Managed Identity.
The links between a Function App and its Storage Accounts are essential for its operation. But they can also represent a security risk if not handled carefully.
It is therefore recommended to eliminate Shared Access Keys or store them securely in Azure Key Vault. Combined with the use of Managed Identities, this ensures secure and reliable connections.
These practices strengthen the protection of exchanges between Azure services without sacrificing flexibility or automation.