Skip to content

Identity-based auth, SAS URLs, and Flex Consumption deploy docs#1

Open
CATDAB wants to merge 1 commit into
NicoPilot-dev:mainfrom
CATDAB:identity-and-flex-deploy
Open

Identity-based auth, SAS URLs, and Flex Consumption deploy docs#1
CATDAB wants to merge 1 commit into
NicoPilot-dev:mainfrom
CATDAB:identity-and-flex-deploy

Conversation

@CATDAB
Copy link
Copy Markdown

@CATDAB CATDAB commented May 19, 2026

Summary

Adapts the app for tenants that enforce StorageAccount_DisableLocalAuth and StorageAccount_BlobAnonymousAccess Azure Policies (the default on most modern enterprise tenants), where the current shared-key + public-blob design fails to deploy. Also updates the deployment docs to reflect what's actually reliable today (Flex Consumption, remote build, identity-based runtime storage).

Discovered while deploying the repo as-is into an M365 dev tenant where both shared-key auth and anonymous blob access are blocked by policy.

Changes

Code

  • function_app.py — dual-mode storage auth (backward compatible). If CHARTS_BLOB_ACCOUNT_URL is set (or CHARTS_BLOB_CONNECTION_STRING has no AccountKey=), use DefaultAzureCredential and return a User Delegation SAS URL with read-only access. Otherwise fall back to the original connection-string + public-blob behavior. SAS TTL configurable via CHARTS_SAS_TTL_DAYS (default 30 days). User delegation key is cached for 24h to avoid one round-trip per upload.
  • requirements.txt — add azure-identity.

Docs and config

  • README.md — rewrite Configuration and Deployment to Azure. Documents both auth modes side by side. Makes Flex Consumption the recommended plan (needed for MCP, supports identity-based runtime/deployment storage cleanly). Shows the full identity-based provisioning recipe: --assign-identity '[system]', --deployment-storage-auth-type SystemAssignedIdentity, AzureWebJobsStorage__accountName + AzureWebJobsStorage__credential=managedidentity, and the three required storage RBAC roles. Adds a note that pre-installing .python_packages locally is a cross-architecture trap (ARM64 dev → x86_64 Linux fails silently); remote build (Oryx) is what Flex does automatically.
  • local.settings.json.example — show both auth modes and add CHARTS_SAS_TTL_DAYS.
  • host.json, openapi.json, copilot-studio-instructions.md — refresh "public URL" wording to reflect the SAS-link default.
  • openapi.json — add the missing chart_type enum values (area, box, violin, heatmap) that function_app.py already supports.

Verification

End-to-end deploy + smoke test in identity mode against an EMU tenant with both policies enforced. The function app provisioned, the code deployed via az functionapp deployment source config-zip --build-remote true, /api/chart returned 200, the SAS URL fetched a 21 KB PNG with Content-Type: image/png.

Backward compat: legacy connection-string mode is preserved untouched — existing deployments using CHARTS_BLOB_CONNECTION_STRING keep returning unsigned public blob URLs exactly as before.

Adapts the app for tenants that enforce StorageAccount_DisableLocalAuth
and StorageAccount_BlobAnonymousAccess Azure Policies (very common in
modern enterprise tenants), where the current shared-key + public-blob
design fails to deploy.

Code:
- function_app.py: dual-mode storage auth. If CHARTS_BLOB_ACCOUNT_URL is
  set (or CHARTS_BLOB_CONNECTION_STRING has no AccountKey), use
  DefaultAzureCredential and return a User Delegation SAS URL with
  read-only access (TTL configurable via CHARTS_SAS_TTL_DAYS, default 30
  days). Otherwise fall back to the original connection-string +
  public-blob behavior. Caches the user delegation key for 24 hours to
  avoid one round-trip per upload.
- requirements.txt: add azure-identity.

Docs and config:
- README.md: rewrite Configuration and Deployment sections. Document
  both auth modes, make Flex Consumption the recommended plan, show
  the identity-based provisioning (--assign-identity, --deployment-
  storage-auth-type SystemAssignedIdentity, AzureWebJobsStorage__
  accountName, three storage RBAC roles), and warn against pre-
  installing .python_packages locally (cross-architecture pitfall).
- local.settings.json.example: show both auth modes side-by-side and
  add CHARTS_SAS_TTL_DAYS.
- host.json, openapi.json, copilot-studio-instructions.md: refresh
  'public URL' wording to reflect the SAS link default.
- openapi.json: add the missing chart_type enum values (area, box,
  violin, heatmap) that function_app.py already supports.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant