Fix Firebase auth on non-primary domains — same-origin authDomain (reverse-proxy /__/auth)
RBAC sequence: independent — an auth-infrastructure fix (cross-domain
authDomain), orthogonal to the RBAC enforcement + people tracks. No precede/succeed; parallelisable. See the sequence map in T-022. (Marked by EOP Local Assistance, 2026-06-23.)
Why (escalated from I-002)¶
p-eop sign-in throws "Unable to save initial state / sessionStorage." Root cause (see ticket I-002):
Firebase signInWithRedirect with a cross-domain authDomain (aote-pms.firebaseapp.com) + browser
storage partitioning. The sign-in code (app/auth/signin/client.tsx) tries signInWithPopup first,
falls back to signInWithRedirect when the popup is blocked (line ~377), and the fallback throws — surfaced
to the user via setError. (getRedirectResult is already caught gracefully at line ~424.) Not Cloudflare,
not authorized-domains, not the baked NEXT_PUBLIC_APP_URL (the code uses window.location.origin).
Fix — same-origin authDomain (Firebase's recommended fix for storage partitioning)¶
Serve Firebase's auth handler first-party so the redirect round-trip stays same-origin:
1. Next.js rewrite: proxy /__/auth/:path* → https://aote-pms.firebaseapp.com/__/auth/:path* (and
/__/firebase/* if needed) in next.config.
2. authDomain = the app's own domain, baked per branch: NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN =
eop.theestablishers.com (main) / p-eop.theestablishers.com (nightly) — add to the per-branch cfg
step in .github/workflows/nas-image.yml (alongside NEXT_PUBLIC_APP_URL).
3. eop + p-eop are already Firebase authorized domains (owner-confirmed), so no console change.
Rollout — preview-first (that's what the split is for)¶
- Deploy to nightly → p-eop FIRST; test Google sign-in on p-eop (popup and redirect paths).
- Promote to
main/eop only after p-eop sign-in is verified — never risk locking the directors out of prod with an untested authDomain change. - Rollback: revert
authDomaintoaote-pms.firebaseapp.com.
Decision log¶
2026-06-21 — escalated from ticket I-002¶
- ✅ Attestation (EOP Local Assistance): read
AGENTS.md; opened this as the structural escalation of ticket I-002 (per the Tickets rule — symptom ticket →T-NNNfor the structural fix). - Source: EOP Local Assistance · session 63c32698-0f80-464c-a668-f352be2c148e (local Claude Code)
- Proposed by: EOP Local Assistance. Approved by: the owner.
- Why routed this way: redirect-based Firebase auth can't be fixed by config alone on a self-hosted multi-domain setup; a same-origin authDomain (reverse-proxied handler) is the standard fix. Deployed preview-first because an untested authDomain change risks breaking prod sign-in.
- Evidence — owner, 2026-06-21 (verbatim):
"Please also proceed to work on I-002"
2026-06-22 — driver changed: p-eop dropped → now latent PROD hardening (low priority)¶
- Source: EOP Local Assistance · session 63c32698-0f80-464c-a668-f352be2c148e (local Claude Code)
- The immediate driver (the p-eop symptom, I-002) is gone — the owner dropped the NAS preview (T-082), so p-eop no longer exists and I-002 is closed. This task is NOT moot, but its urgency drops sharply.
- Why keep it open: the same cross-domain
authDomain(aote-pms.firebaseapp.com) +signInWithRedirectfragility latently affects prod (eop) — if a director's browser ever blocks the Google sign-in popup, the redirect fallback could throw the same "Unable to save initial state" error and lock them out of prod. The same-originauthDomainfix (above) is cheap insurance against that. - Reframed scope: harden eop (prod) auth only — bake
authDomain = eop.theestablishers.comfor main (drop the per-branch p-eop bit from step 2). Low priority — no active symptom; popup works today. Revisit if a sign-in failure is ever reported on eop, or fold it into the eventual prod→Vercel move (T-082).
2026-07-09 — dropped: driver dead (p-eop retired); remnant folded into T-154¶
- ✅ Read AGENTS.md. Outcome/verdict: never started; closing without work commits (no SHAs to list).
The task existed to fix sign-in on p-eop (I-002) — that host was retired 2026-06-22 and hosting
moved back to Vercel, so the driver no longer exists; production sign-in on eop.theestablishers.com
works (popup path). Surviving remnant: the popup-BLOCKED
signInWithRedirectfallback still breaks under browser storage partitioning with the cross-domainauthDomain— classically iOS Safari — and is now a scoped item inside T-154 (iOS 26 Safari optimization), where the same-origin authDomain / reverse-proxy/__/authfix from this task's body remains the reference design. Blast radius: none (no code changed). Owner approval (2026-07-09, verbatim): "Do the board hygiene and route T-038, T-040, T-072, T-083, T-051". - Source: EOP Local Assistance (fork) · session edb0abc7-6373-449b-8e31-379fd38d391b