Protect Azure Function’s internal Storage via PrivateLink

Every Azure Function instance requires to have a Azure Storage Account for storing sensitive data – sometimes even source code of functions. Out of the box, this storage has enabled public endpoint. With PrivateLink, you can add an extra layer of protection.

What data are stored inside Storage Account

Azure Function App uses two subservices blob and files in the Storage Account. It always creates a two blob containers, called azure-webjobs-hosts and azure-webjobs-secrets.

In the azure-webjobs-hosts container – there are metadata files used for logging purposes, locks etc.

In the container azure-webjobs-secrets you can find really interesting data:

  1. every function has JSON file
  2. there is host.json file, containing all function’s keys, including master FunctionApp key, in encrypted form

Function Apps, not using deployment type app package, also stores even functions source code in File shares container, in the site/wwwroot directory.

Out-of-the-box setup

When you create a new Function App via standard Azure Portal wizard, it creates automatically a Storage Account. This Storage Account has opened public endpoint and the Function App interacts with storage via SAS (Shared Access Signature) via public endpoint.

This is not so dangerous setup. as you could read it for first time – all file containers in this Storage Account has for Public access level value Private, so you still need to have storage access key for accessing these files.

On the other hand, in this setup, with a combination of some vulnerability, you could get the content on storage easily compromised and for some workloads you need to reduce the risk with adding extra layer of protection.

Standard deployment architecture of storage for FunctionApp

This setup is based on limiting access to the Storage Account and requires having a vNET. Public endpoint of Storage Account is disabled and there is created a PrivateLink endpoint of the Storage Account into Function App’s vNET.

PrivateLink deployment architecture of storage for FunctionApp


The Function App need to have a plan supporting vNET integration for egress traffic (higher App Service tier, or for consumption-based resources you need to have a Premium plan).

Storage Account needs to be provisioned as General purpose V2 account kind (V1 is not supported by PrivateLink).


I am reminding this, because it happened to me, that Azure Portal user wizard created a V1 Storage Account for Function App. When this happens, just create a new V2 Storage Account and point the Function App to the new storage resource.

Steps to protect Azure Function (via Azure Portal)

Turn off public endpoint on Storage Account

  1. Go to Networking, select Allow access from selected networks and click Save
  1. Go to Networking, select tab Private Endpoint connections and click on +Private Endpoint

  2. Follow wizard, as resource select the Storage Account resource

  3. As target sub-resource select blob value

  4. Repeat steps, only as a target sub-resource select file value

Set up required feature flag for Function App runtime

  1. Go to the Function App resource, select Configuration and select tab Application settings
  2. Add a new Application settings called WEBSITE_CONTENTOVERVNET, with value 1
  3. Save new settings
  4. Test the Function App

Now the Storage Account is not accessible from public internet, but reachable from the Function App.

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy