Admin auth, one source of truth โ
- Status: not started, opened 2026-08-23.
- Issue:
#886: security(auth): admin authorization has two sources of truth, and a partial demotion fails open - Launch plan: none found.
ALPHA.mdhas no row citing #886, which is worth reconciling: a fail-open on admin authorization is not obviously off the alpha path.
What is this? โ
Admin authorization has two sources of truth, so a partial demotion fails open. โ
- The two are the role claim on the token and the
adminfield on the users document, and different services trust different ones. - The consequence: the claim says user, the document still says admin, and six services grant on the document alone.
The scope is already decided, and it is option A. โ
- Convert the 12 either-or and doc-only sites to one shared predicate where a present claim is authoritative and the users document is consulted only when the claim is absent.
What is the current state? โ
The census is done and landed. The fix has not started. โ
- It shipped on dev in
#949: fix(admin): onboard admins with a portal password, and census every admin-role decision site, commit9bda3c83. - It found 19 sites across the services plus 4 on the client, in three shapes.
- It was built by READING every service's middleware, after an earlier grep-built census structurally missed three services (venues, analytics, docs) that gate admin on the users document alone.
- Only
README.mdexists in this project so far.
What else is related? โ
#939: security(rules): firestore.rules trusts only the role claim, so a direct Identity Toolkit token gets admin-level client reads without the portal. Afirestore.ruleschange and the operator's alone, so it is out of scope here without her word.#941: onboard admins with a portal password, closed, shipped in #949.
Do not write to uid 4eLDbNWJ. โ
- It is the one live half-demoted admin on dev: made admin in January, demoted, and the demotion died after its first write. No audit row, no sign-in since 30 January, and nothing denies it.
- Any test that writes to that account destroys the evidence an audit would read. What happens to it is the operator's call and it is still open.