For Linux Consumption, the supported secretless pattern is to run from an external package URL in private Blob Storage and let the function app read that package by managed identity. The documented configuration is:
- Upload a ready-to-run
.zip package to Blob Storage.
- Grant the function app identity Storage Blob Data Reader on the package blob or container.
- Set
WEBSITE_RUN_FROM_PACKAGE to the blob URL.
- Optionally set
WEBSITE_RUN_FROM_PACKAGE_BLOB_MI_RESOURCE_ID to the user-assigned identity resource ID, or use SystemAssigned/omit it for system-assigned identity.
- Restart the function app.
- Manually sync triggers after publishing an updated package. If the package contents change without changing the URL, restart before syncing triggers.
For this hosting plan, that is the recommended deployment route when avoiding SAS-based deployment. Managed identity is recommended over SAS because SAS tokens expire and require maintenance.
The context does not document any Azure Functions or Blob Storage runtime difference where identical package bytes behave differently solely because the blob was uploaded with Entra/OAuth versus Shared Key. It also does not document a package-mount behavior that depends on the upload authentication method.
Supported conclusions from the documented behavior:
- Linux Consumption does not support
WEBSITE_RUN_FROM_PACKAGE=1; it must use an external package URL.
- External package URL is the only supported deployment method for Linux Consumption when a remote build is not wanted.
- The package must be a ready-to-run
.zip with host.json at the root.
-
wwwroot is mounted read-only from the package.
- After each updated package publication, trigger sync is required.
- If using ZIP push deployment tooling such as AzureFunctionApp@1, that path sets
WEBSITE_RUN_FROM_PACKAGE to a SAS-based URL and there is currently no option in that task to suppress the SAS token. To use managed identity, the package upload and app-setting update must be managed directly.
Based on the documented guidance, the correct secretless CI/CD pattern for Linux Consumption is:
- Build the ready-to-run ZIP.
- Upload the ZIP to a private Blob container.
- Keep
WEBSITE_RUN_FROM_PACKAGE set to the blob URL without SAS.
- Ensure the function app managed identity has Storage Blob Data Reader.
- Set
WEBSITE_RUN_FROM_PACKAGE_BLOB_MI_RESOURCE_ID=SystemAssigned only if needed for clarity.
- Restart the app.
- Manually sync triggers.
A practical diagnostic checklist supported by the documentation is:
- Verify the app is still using an external package URL, not
WEBSITE_RUN_FROM_PACKAGE=1.
- Verify the blob URL in
WEBSITE_RUN_FROM_PACKAGE points to the intended package.
- Verify the function app identity has Storage Blob Data Reader on the blob or container.
- If a user-assigned identity is intended, verify
WEBSITE_RUN_FROM_PACKAGE_BLOB_MI_RESOURCE_ID is the exact resource ID; otherwise use SystemAssigned or omit it.
- Restart the function app after changing app settings or replacing package content.
- Manually call trigger sync after each package update.
- Confirm the package is a
.zip and remains a ready-to-run app package.
One important limitation is also documented: an existing app already using WEBSITE_RUN_FROM_PACKAGE=1 cannot be changed to external package URL mode; a new function app is required for that transition. That does not apply if the app is already using the blob URL pattern.
If the app still fails only for OAuth-uploaded blobs after the documented managed-identity configuration, restart, and manual trigger sync, the context provides no documented product behavior explaining that upload-method-specific difference.
References: