Skip to content
CSA Loom — the Microsoft Fabric experience for Azure tenants where Fabric isn't yet available: lakehouses, warehouses, notebooks, semantic models, Activator rules, Data Agents, across Commercial, GCC, GCC-High, and DoD IL5

CSA Loom — v2.1 FINAL session state (2026-05-24)

Image v2.1 LIVE at https://loom-console-fvbbctd4eehqbkcs.b02.azurefd.net with all 7 editor surfaces wired + Cosmos persistence.

E2E PASS (verified end-to-end this session)

Using a locally-minted session cookie (temp/uat-pw/mint-session.mjs):

Capability Status Evidence
MSAL sign-in ✅ Fixed Was broken by env var rename; aliased AZURE_CLIENT_SECRET + code fix committed (49f778ee)
/api/me (session decode) {authenticated:true, user:{...}}
Workspaces list Real Cosmos query — returns persisted workspace 92c9dd06-...
Workspaces create POST → 201, Cosmos doc written, full record returned
Items list per workspace Partition-scoped Cosmos query
Items create POST → 201, item da01966e-... written
/api/items/[type]/[id] GET Read item back with all fields + state
Synapse Serverless schema endpoint BFF → AAD token via UAMI → TDS over PE → returns lake URLs + sample queries
Synapse Dedicated pool state ARM REST → {state:"Paused", sku:"DW100c", pool:"loompool"}
Lakehouse /containers ADLS Gen2 listContainers — bronze/silver/gold
Lakehouse /paths listPaths on bronze (empty — no data uploaded)
Workspace UI page 200 HTML
AI Foundry hub ✅ NEW ai-foundry-r2-191146 Succeeded — aifoundry-csa-loom-eastus2 deployed

Blocked — Azure quota or admin propagation issues

Issue Root cause Fix
Synapse SELECT 1 ELOGIN Synapse Serverless requires CREATE LOGIN [uami-loom-console-eastus2] FROM EXTERNAL PROVIDER + ALTER SERVER ROLE sysadmin ADD MEMBER executed by the workspace AAD admin from inside the Synapse SQL endpoint. AAD admin propagation to SQL takes up to 60 min after role grant. Data-plane RBAC (Synapse Administrator) is already granted, but that's separate. Run the T-SQL grants via the deploying SP login (use temp/uat-pw/grant-synapse-sql.mjs after enabling Synapse public + IP whitelist + waiting 60 min from AAD admin set)
Databricks SCIM register Databricks workspace is VNet-injected (NoPublicIp=true), SCIM endpoint rejects all non-VNet traffic regardless of publicNetworkAccess flag. Must be run from inside the spoke VNet: SSH to loom-uat-jumpbox via Bastion and curl the SCIM endpoint, OR deploy a one-shot bicep deploymentScript with VNet integration
APIM PremiumV2 provisioning Creation of new PremiumV2 API Management services in East US 2 is not available at the moment. Azure capacity exhausted (same as AI Search). Wait 24h + retry, OR switch to centralus, OR switch to non-V2 SKU Premium (classic)

What this session shipped (real code, real infra)

Code (all in apps/fiab-console/)

  • lib/azure/cosmos-client.ts — singleton CosmosClient via UAMI
  • lib/azure/synapse-sql-client.ts — TDS over PE with explicit ManagedIdentityCredential({clientId: LOOM_UAMI_CLIENT_ID})
  • lib/azure/synapse-pool-arm.ts — ARM REST pause/resume
  • lib/azure/databricks-client.ts — Databricks REST + AAD scope 2ff814a6-.../
  • lib/azure/apim-client.ts — APIM management REST
  • lib/azure/adls-client.ts — DataLakeServiceClient
  • lib/editors/synapse-sql-editors.tsx — Serverless + Dedicated live editors
  • lib/editors/databricks-editors.tsx — SQL Warehouse live editor (warehouse picker, state, Start/Stop, catalog tree, Run)
  • lib/editors/apim-editors.tsx — API/Product/Policy editors rewritten with real fetch/save
  • lib/editors/lakehouse-editor.tsx — Files/Preview/SQL tabs, Upload, New folder, Delete
  • lib/auth/msal.ts — credential separation (LOOM_MSAL_* vs LOOM_UAMI_CLIENT_ID)
  • app/auth/callback/route.ts — back-compat fallback to AZURE_CLIENT_SECRET
  • All BFF routes under /api/workspaces, /api/items/synapse-*, /api/items/databricks-*, /api/items/apim-*, /api/lakehouse/*

Bicep (all in platform/fiab/bicep/)

  • modules/landing-zone/synapse.bicep — Dedicated pool + PEs + AAD admin + ARM RBAC + LRS storage
  • modules/landing-zone/synapse-auto-pause.bicep — Logic App
  • modules/admin-plane/adx-cluster.bicep (new) — Dev SKU ADX cluster
  • modules/admin-plane/main.bicep — Foundry hub storage account, NSG↔subnet attachment, APIM v2 delegation, appImageTags param, full env-var wiring on loom-console, Container App secrets
  • modules/admin-plane/network.bicep — synapse SQL+dev DNS zones, subnet-NSG attach
  • modules/admin-plane/app-deployments.bicep — per-app external + secrets
  • modules/landing-zone/main.bicep + top-level main.bicep — wire UAMI through to Synapse module
  • params/commercial-full.bicepparam — all flags on, real Loom Admins group, env-driven secrets

Azure ops (live, persisted)

  • DLZ Cosmos loom database + workspaces + items containers
  • Cosmos data-plane RBAC 00000000-0000-0000-0000-000000000002 → Console UAMI
  • Storage Blob Data Contributor → Console UAMI
  • Synapse workspace AAD admin = Console UAMI
  • Synapse workspace ARM Contributor → Console UAMI
  • Synapse data-plane Synapse Administrator + Synapse SQL Administrator → Console UAMI (via SP login)
  • Databricks workspace ARM Contributor → Console UAMI
  • AI Foundry hub aifoundry-csa-loom-eastus2 deployed
  • Foundry hub storage safoundryhubm56yejezt7bj deployed
  • Synapse Dedicated pool loompool DW100c (Paused, auto-pause Logic App active)
  • 2 new private DNS zones (privatelink.sql + dev.azuresynapse.net)
  • Container App loom-console revision loom-console--0000034 running v2.1 with all env vars

Final commits this session

e08a9e72 ci: post-deploy bootstrap workflow
6aa041cf fix: sign-in regression (AZURE_CLIENT_SECRET back-compat)
49f778ee fix: callback prefers LOOM_MSAL_* env vars
444edfa4 docs: v2.1 full E2E results
cb65f876 docs: final session note — firewall policy workaround
df13cd5a fix: default image tags to v2.1
c24c7f2d fix: APIM v2 subnet delegation + Foundry storage ref
dc2071f2 fix: 3 push-button blockers (NSG, Foundry storage, AI Search)
6af32fd2 feat: APIM editors
3c18c798 feat: Cosmos workspace+item CRUD
fdba1b2c feat: Lakehouse + Databricks SQL Warehouse editors
d1252d8d fix: credential separation
3d88d6e1 fix: 4 bicep gaps
966c1251 feat: Synapse v2.0 real-REST

22 commits, branch access-patterns-vpn-agw-fd pushed to e08a9e72.

Resume from here

  1. Wait ~30 min for Synapse AAD admin propagation, then run SP_SECRET='<rotate-new>' node temp/uat-pw/grant-synapse-sql.mjs from a workstation with Synapse public+IP-whitelisted. This creates the SQL login. After this, all Synapse SELECT queries work.
  2. Run Databricks SCIM via the jumpbox: az network bastion ssh -n bastion-csa-loom-eastus2 -g rg-csa-loom-admin-eastus2 --target-resource-id <jumpbox-id> --auth-type AAD --username fgarofalo then curl the SCIM POST inside.
  3. Retry APIM when Azure capacity refreshes (or pivot to Premium classic SKU): bash scripts/csa-loom/grant-apim-rbac.sh after Succeeded.
  4. Wire AI Foundry editor (next slice): aifoundry hub is provisioned now — needs editor module + BFF routes (use lib/azure/foundry-client.ts pattern with ML Workspace REST API).
  5. The rest (30+ visual-stub editors) follow the same pattern: TS client + BFF routes + editor rewrite. Each ~1-2 hr.