2026-06-09 — Resync infra/main.json with committed Bicep (phase-1 RBAC + STORAGE_ACCOUNT_NAME)¶
Motivation¶
The compiled deployment template infra/main.json had drifted behind its Bicep
source. Two sets of source-only changes were never recompiled into the JSON:
- Phase-1 narrow RBAC roles (commit
0aacd26, "audit P2 #16-20"): thecontrolPlaneRoles.bicep/workloadClusterRoles.bicepmodules addedmanagedIdentityContributorRoleId,networkContributorRoleId, andaksContributorRoleIdrole assignments for the shared UAMI — but that commit did not regeneratemain.json, so the phase-1 ADD never reached the deployable template (anazd provisionwould not have created those roles). STORAGE_ACCOUNT_NAMEon the api/worker sidecars (commitb88113e, prior session): the Bicep module + module JSON were updated, butmain.jsonwas intentionally left untouched at the time to avoid pulling in the stale RBAC drift mid-session.
This change recompiles main.json from the current Bicep so the deployable
template matches source again.
Change¶
infra/main.jsonregenerated frominfra/main.bicepviaaz bicep build. Regeneration is idempotent (built twice → byte-identical).
Safety audit (charter §12a — RBAC is ADD-only)¶
The regenerated diff was statically audited to confirm it only adds role assignments and never removes one (the §12a Rule 1 ADD-then-REMOVE invariant):
Microsoft.Authorization/roleAssignmentsresources: +12 added, −0 removed.roleDefinitionIdreferences: +6 added, −0 removed.- The only non-additive
−lines are benign JSON reformatting: trailing-comma insertions onuserAccessAdministratorRoleId/platformResourceGroupName(a new sibling var now follows them), twodescriptiontext refreshes, and the single minifiedcontainersline being regenerated to includeSTORAGE_ACCOUNT_NAMEon api/worker. No role assignment, principal, or scope was deleted.
This is exactly the phase-1 ADD the 0aacd26 commit intended; the broad
Contributor / User Access Administrator assignments are preserved (the
phase-2 REMOVE is a separate, later PR per Rule 1).
Validation evidence¶
az bicep build infra/main.bicep→ exit 0; second build byte-identical (idempotent).main.jsonis a well-formedsubscriptionDeploymentTemplate(14 root resources).uv run pytest -q api/tests/test_check_rbac_removal.py→ 66 passed.az deployment sub what-ifcould not run end-to-end: it fails on a pre-existinglockdownPrivateNetworkingparameter type mismatch in the parameters file (String vs Boolean), unrelated to this template regeneration. The static ADD-only audit above stands in for the automated removal check.
Remaining / follow-up¶
- The
lockdownPrivateNetworkingparameter type mismatch ininfra/main.parameters.json(or the azd env) blocksaz deployment sub what-if; worth fixing separately so the §12a Rule 7 preflight can run clean. - A full
azd provisionwill now create the phase-1 narrow RBAC roles. The phase-2 REMOVE of the broad roles remains a separate future PR (Rule 1).