SPRINT-7 Gate T4-R Report — last1.app Browser E2E + GoTrue Provider Sweep¶
Date: 2026-08-30
Status: T4-R PASS (Ryan sign-off). T-4 closes.
Prior: SPRINT7_T4_REPORT.md (automated DNS cutover)
Executive summary¶
Ryan completed browser E2E on production https://last1.app against R940 (monolith VM 121, sovereign DB/auth VM 103). Last1 ID OAuth and Google OAuth both work end-to-end. Warriors In Need org dashboard and data load from R940 (T4-R data test, not auth-only).
During T4-R, sovereign GoTrue was missing Google OAuth env (same class of gap as Onset Apple post-restore). Fixed and verified. A full auth provider sweep shows Phone OTP (Twilio) and Apple SIWA still not migrated to sovereign GoTrue — T-5 blockers for RadioCheck iOS, not T-4 web cutover blockers.
1. T4-R browser E2E (Ryan)¶
| Step | Result | Notes |
|---|---|---|
Open https://last1.app (fresh session) |
PASS | R940 via Cloudflare tunnel; no Railway headers |
| Last1 ID OAuth login | PASS | ryan@last1.enterprises, curryrg@gmail.com |
| Google OAuth login | PASS | After GoTrue credential fix (§2) |
| Open Warriors In Need org dashboard | PASS | Org data renders (programs/dashboard), not stale Railway |
| Org-scoped spot check | PASS | Ryan confirmed coherent org load post-Google-login |
Data test anchor (R940 DB):
| Field | Value |
|---|---|
| Org ID | 7b975ed9-373e-4874-b8b1-88e1950027b5 |
| Slug | warriors-in-need |
| Programs (R940) | 3 active (Test Program, Veteran Employment Services, Warriors in Need (MOCK Pipeline)) |
ryan@last1.enterprises |
organization_members.role = admin for WIN |
Monolith DATABASE_URL → 192.168.1.103:5432 (sovereign). Session store on same Postgres.
2. Google OAuth fix (sovereign GoTrue, VM 103)¶
Symptom chain¶
- Client bundle pointed at
https://last1app-db.last1.enterprises(fixed earlier in T-4 prep). - GoTrue returned
400 Unsupported provider: provider is not enabled— Google commented out indocker-compose.yml+ placeholder.env. - After enablement, token exchange failed:
invalid_client/ wrong client ID, then wrong client secret.
Root cause¶
GoTrue provider config does not ride pg_dump/restore. Sovereign stack came up with DB rows but disabled/missing external OAuth env. BWS initially held the deleted legacy client (645620802422-4ce80057…) and a non-matching secret.
Fix applied¶
Scripts (repo): scripts/last1app/configure-last1app-google-oauth.sh, fetch-last1app-google-from-hosted.py, push-last1app-google-oauth.sh.
| Setting | Value |
|---|---|
GOTRUE_EXTERNAL_GOOGLE_ENABLED |
true |
| Client ID | 645620802422-2eur6s5chutdr5kouohnkdgqostcl2d4.apps.googleusercontent.com |
| Redirect URI | https://last1app-db.last1.enterprises/auth/v1/callback |
SITE_URL |
https://last1.app |
ADDITIONAL_REDIRECT_URLS |
https://last1.app/auth/callback |
| BWS keys | LAST1APP_DB_PROD_GOOGLE_OAUTH_CLIENT_ID, LAST1APP_DB_PROD_GOOGLE_OAUTH_SECRET |
GCP: Ryan added authorized redirect URI for sovereign callback on client 2eur6s5….
Verification¶
| Check | Result |
|---|---|
GET …/auth/v1/settings → google: true |
PASS (LAN + public) |
| Authorize → Google 302 | PASS |
| Token exchange (Google API probe) | PASS after secret correction |
| Ryan browser Google login + callback | PASS |
| WIN dashboard after Google login | PASS |
3. Google client identity (not cross-wired)¶
| Client | GCP project | Product | Sovereign? | Notes |
|---|---|---|---|---|
645620802422-2eur6s5… |
last1app (645620802422) |
last1.app + RadioCheck bundle | Yes (live) | Replaced deleted 4ce80057…; authorize + login verified |
645620802422-4ce80057… |
same | Legacy bundle client | Deleted (W7-5) | Was hosted client pre-rotation; must not return to sovereign |
889079898378-… |
Last1.id project | last1.id only | VM 114 | Wrong product if used on last1app-db |
911218996408-… |
last1-admin | last1-admin | N/A | Wrong inference caused last1.id redirect_uri_mismatch (Week 4) |
Conclusion: 645620802422-2eur6s5chutdr5kouohnkdgqostcl2d4 is the correct current Google OAuth client for the last1.app / RadioCheck shared Supabase bundle on GCP project last1app. It is not the last1.id or last1-admin client. Ryan confirmed functional login after pairing with the matching GCP client secret.
Hosted rollback net note (2026-08-30): Hosted authorize probe returned client 4ce80057… after today's secret work — hosted Google may be mis-pointed again. Rollback net only; sovereign path is correct. Reconcile hosted Auth → Providers → Google before relying on hosted Google during rollback.
4. GoTrue provider sweep — sovereign vs hosted (VM 103)¶
Compared GET /auth/v1/settings and /opt/supabase/docker/.env + running supabase-auth env.
| Provider | Hosted tcthzakppndkykatoefx |
Sovereign last1app-db |
Credential status (sovereign) | T-5 impact |
|---|---|---|---|---|
| enabled | enabled | BWS LAST1APP_DB_PROD_GOOGLE_OAUTH_* + GCP redirect |
Web PASS (T4-R) | |
| Email/password | enabled, mailer_autoconfirm: true |
enabled, mailer_autoconfirm: false |
Fake SMTP (supabase-mail, fake_mail_*) — no real mailer |
Password reset / magic link broken on sovereign until SMTP migrated |
| Phone OTP | enabled, sms_provider: twilio, autoconfirm false |
enabled, sms_provider: "" (empty), autoconfirm true |
Twilio vars in .env for Edge functions only; GoTrue GOTRUE_SMS_* / Twilio lines commented out in compose |
CRITICAL — RadioCheck iOS primary auth |
| Apple SIWA | enabled; authorize uses Services ID auth.last1.radiocheck |
disabled | No GOTRUE_EXTERNAL_APPLE_* in compose; no LAST1APP_*_APPLE_* in BWS |
CRITICAL — RadioCheck Pro SIWA backup |
Phone OTP detail¶
.envhas live Twilio SIDs (TWILIO_ACCOUNT_SID,TWILIO_AUTH_TOKEN,TWILIO_MESSAGING_SERVICE_SID) wired to edge-runtime for SMS functions.- GoTrue auth container:
GOTRUE_SMS_PROVIDER,GOTRUE_SMS_TWILIO_*remain commented → settings reportsms_provider: "". - T-5 action: Uncomment/patch compose + set
SMS_PROVIDER=twilio, map Twilio creds from BWS (LAST1APP_APP_PROD_TWILIO_*), alignphone_autoconfirmwith hosted (falsefor real OTP).
Apple SIWA detail¶
- Hosted authorize:
client_id=auth.last1.radiocheck→ Apple Services ID for RadioCheck (not OnsetTU6S85XABQ). - T-5 action: Add
configure-last1app-apple-oauth.sh(pattern:scripts/onset/configure-onset-gotrue-apple.sh), BWS keys for team/key/services ID +.p8, enable compose passthrough, verifyapple: trueon publiclast1app-db.last1.enterprises.
5. Gate status¶
| Gate | Status |
|---|---|
| T-4 automated (DNS, smoke, cron) | PASS — SPRINT7_T4_REPORT.md |
| T4-R browser + data | PASS — this report |
| T-4 | CLOSED |
T-5 entry conditions (unchanged): api.last1.app, RadioCheck iOS pointer, hosted teardown prep — plus GoTrue Phone + Apple migration from §4 before pointing live iOS at sovereign auth.
6. Scripts added (last1app-db GoTrue)¶
| Script | Purpose |
|---|---|
scripts/last1app/configure-last1app-google-oauth.sh |
Enable Google on VM 103 from env/BWS |
scripts/last1app/fetch-last1app-google-from-hosted.py |
Pull hosted auth config via Management API (needs SUPABASE_ACCESS_TOKEN) |
scripts/last1app/push-last1app-google-oauth.sh |
Fetch → BWS → SSH configure |
STOP¶
T-4 + T4-R complete. Proceed to T-5 planning with provider sweep gaps as explicit pre-flight work.