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 UAMIlib/azure/synapse-sql-client.ts— TDS over PE with explicitManagedIdentityCredential({clientId: LOOM_UAMI_CLIENT_ID})lib/azure/synapse-pool-arm.ts— ARM REST pause/resumelib/azure/databricks-client.ts— Databricks REST + AAD scope2ff814a6-.../lib/azure/apim-client.ts— APIM management RESTlib/azure/adls-client.ts— DataLakeServiceClientlib/editors/synapse-sql-editors.tsx— Serverless + Dedicated live editorslib/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/savelib/editors/lakehouse-editor.tsx— Files/Preview/SQL tabs, Upload, New folder, Deletelib/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 storagemodules/landing-zone/synapse-auto-pause.bicep— Logic Appmodules/admin-plane/adx-cluster.bicep(new) — Dev SKU ADX clustermodules/admin-plane/main.bicep— Foundry hub storage account, NSG↔subnet attachment, APIM v2 delegation,appImageTagsparam, full env-var wiring on loom-console, Container App secretsmodules/admin-plane/network.bicep— synapse SQL+dev DNS zones, subnet-NSG attachmodules/admin-plane/app-deployments.bicep— per-appexternal+secretsmodules/landing-zone/main.bicep+ top-levelmain.bicep— wire UAMI through to Synapse moduleparams/commercial-full.bicepparam— all flags on, real Loom Admins group, env-driven secrets
Azure ops (live, persisted)¶
- DLZ Cosmos
loomdatabase +workspaces+itemscontainers - 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-eastus2deployed - Foundry hub storage
safoundryhubm56yejezt7bjdeployed - Synapse Dedicated pool
loompoolDW100c (Paused, auto-pause Logic App active) - 2 new private DNS zones (privatelink.sql + dev.azuresynapse.net)
- Container App
loom-consolerevisionloom-console--0000034running 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¶
- Wait ~30 min for Synapse AAD admin propagation, then run
SP_SECRET='<rotate-new>' node temp/uat-pw/grant-synapse-sql.mjsfrom a workstation with Synapse public+IP-whitelisted. This creates the SQL login. After this, all Synapse SELECT queries work. - 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 fgarofalothen curl the SCIM POST inside. - Retry APIM when Azure capacity refreshes (or pivot to Premium classic SKU):
bash scripts/csa-loom/grant-apim-rbac.shafter Succeeded. - Wire AI Foundry editor (next slice): aifoundry hub is provisioned now — needs editor module + BFF routes (use
lib/azure/foundry-client.tspattern with ML Workspace REST API). - The rest (30+ visual-stub editors) follow the same pattern: TS client + BFF routes + editor rewrite. Each ~1-2 hr.