Enable RBAC enforcement — strict Security Rules (all DBs) + position claims + flip RBAC_ENABLED
Goal¶
Make user access to Firestore enforced by the DATABASE, not just remembered in code: user-facing reads/writes go through the Firebase CLIENT SDK gated by Security Rules + custom claims; the Admin SDK is reserved for privileged/derived/ integration ops (journals, reports, bank/Drive/GCP/Telegram, claim mints, cross-entity admin).
Key finding (2026-06-13 scoping)¶
This is ~80% ALREADY BUILT, behind the RBAC_ENABLED flag:
- lib/rbac/ — claims.ts, permissions.ts, subsidiaryAccess.ts, types.ts, config.ts.
Custom claims (role/status/subsidiaries/primarySubsidiary) synced on profile
create/update + sign-in, even while RBAC_ENABLED=false (SYNC_CLAIMS_WHEN_DISABLED).
- Security Rules files for ALL 4 DBs (firestore.{tebs-erl,tebs-mel,tebs-epl,aote-system}.rules)
wired in firebase.json — currently PERMISSIVE; STRICT role+subsidiary versions
written but commented out.
- Client SDK already used in some components (StudentDialog); user profiles in
aote-system/users with role + subsidiaryAccess; roles: super_admin / admin /
auditing_accountant / bookkeeper / project_admin / pending.
So the work = FINISH + ENABLE, not design from scratch: tighten/verify the strict
rules (incl. for the migrated documents per T-021), decide which Admin-SDK
reads move client-side, scope per-DB, add a Rules test plan, flip the flag.
This task vs siblings (RBAC initiative)¶
T-022 is now scoped to the ENABLE step only. The other surfaces are their own UIDs:
- T-025 — migrate user-facing Firestore reads/writes to the client SDK.
- T-026 — re-introduce the firestore.rules CI auto-deploy workflow.
- T-027 — narrow the Firestore Admin SDK credential (per-database SA scoping).
So T-022 = tighten/verify the strict (commented) Security Rules for all 4 DBs incl.
the migrated documents (T-021), complete position-level claims, add a Rules
test plan, and flip RBAC_ENABLED.
SA coordination — answered 2026-06-13 (UNBLOCKED, zero conflict)¶
The SA-refactoring agent's refactor is pure GCP IAM and orthogonal to all auth work:
- App's Firestore cred = firebase-adminsdk-fbsvc@aote-pms (FIREBASE_ADMIN_PROJECT_ID/
_CLIENT_EMAIL/_PRIVATE_KEY in Vercel) — UNTOUCHED by their refactor; still
datastore.owner + firebase.sdkAdminServiceAgent at project scope. Narrowing
it is mine → T-027.
- They are NOT touching Firebase Auth, custom claims, providers, or NextAuth.
Claims (subsidiary + position/role) are entirely mine — ship anytime.
- Client SDK + Security Rules are mine — ship anytime; NO timeline constraints.
- CI: firebase-rules-deployer@ (role firebaserules.admin) + GH secrets
FIREBASE_DEPLOY_KEY + FIREBASE_ADMIN_PROJECT_ID are ALREADY provisioned to
auto-deploy firestore.*.rules; the workflow file was reverted at 93e64a2
(branch claude/audit-user-access-control-cch7t) and must be re-introduced →
T-026 (coordinate with the user-access-control session, not the SA agent).
- Their ask back: if I mint any new SA, note it in memory project_sa_audit_aote_pms.
- Caveat: MEL/EPL not yet incorporated → tebs-mel/tebs-epl are conceptual; tebs-erl
is the only real subsidiary DB; aote-system is system-config.
Log¶
- 2026-06-13 created (was blocked on SA answers).
- 2026-06-13 UNBLOCKED + re-scoped to the enable step; SA answers recorded; split client-SDK migration / CI workflow / SA-scoping into T-025/026/027.