Securing connection between Storage Accounts and Function Apps

Published by Dylan DAUTHEVILLE
Category : Azure / Azure Functions / Entra Id
05/09/2025

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.

 

Links Between Storage Accounts and a Function App

 

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:

 

Function App Settings

 
 

AzureWebJobsStorage

The first connection to a Storage Account is Azure Web Jobs Storage. In this Storage Account, the Function App creates two blob containers:

 

Storage Account Containers

 

  • Azure-webjobs-hosts, which contains information such as the bindings of Azure Functions (like the reader position of an Event Hub, or details required to trigger a Function).
  • Azure-webjobs-secrets, which stores the secrets used to call the Function App (Master Key, Function Key, etc.).

 

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.

 

WEBSITE_CONTENTAZUREFILECONNECTIONSTRING & WEBSITE_CONTENTSHARE

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.

 

How Does the Function App Access the Storage Account by Default?

 

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:

  • You must manage and store the key somewhere.
  • If the key changes, you must update it in the Function App.
  • If a malicious actor gains access to this key (visible in settings), it can create a serious security breach.

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:

  • System Assigned Identity: tied directly to the resource.
  • User Assigned Identity: created separately and assigned to one or multiple resources.

Managed Identities allow secure connections between Azure components without handling access keys or secrets.

 

Securing Azure Web Jobs Storage

 

To configure your Function App to connect to the Azure Web Jobs Storage via a Managed Identity, follow these steps:

Assign a Managed Identity to the Function App

    • In the Identity section, choose the type (System Assigned or User Assigned).
      • For System Assigned, simply toggle the status to “On.”
      • For User Assigned, add the previously created identity.

 
Managed Identity Assignment
 
 

Assign permissions to the Managed Identity on the Storage Account

      • In the Storage Account, go to Access Control (IAM).
      • Add the role Storage Blob Data Contributor to your Managed Identity.

 
Storage Account Role Assignment
 
 

Update Function App settings to use the Managed Identity

Replace the AzureWebJobsStorage App Setting with the following three settings:

      • AzureWebJobsStorage_accountName → the name of the Storage Account
      • AzureWebJobsStorage_clientId → the client ID of the Managed Identity
      • AzureWebJobsStorage_credential → set to "managedIdentity"

 

App Settings Changes

 

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).

 

Shared Key Access Disabled

 
 

Securing Website Content File Storage

 

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:

 
Secret creation for SAS Key
 

Configure the Function App to reference the value from Key Vault using its Managed Identity.

    • Assign the role Key Vault Secrets User to the Managed Identity so it can access the secret.

 
Key Vault role assignment
 

    • In the Function App’s App Settings, reference the secret as follows:

@Microsoft.Keyvault(SecretUri={LeLienDuKeyvault}/secrets/{leNomDuSecret})

 

App Setting with key vault value

 

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.

 

additional App Setting 1

 

Before deployment, make sure an Azure File Storage container already exists in the Storage Account. Its name must match the WEBSITE_CONTENTSHARE parameter.

 

additional App Setting 2

 

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.

 

new file share container

 

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.

 

Conclusion

 

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.