Skip to content

Tier 4 Onset T-3 Gate E Report — Partial GoTrue Retirement (Clinic Off, iOS On)

Status: PASS — Ryan signed 2026-08-30 (Gate F closeout)
Date: 2026-08-29 (E-3 device pass); closeout 2026-08-30
Prior: TIER_4_ONSET_T3_GATE_D_REPORT.md (PASS — curryrg@gmail.com dashboard login)
Contrast: SPRINT-2_GATE_E_REPORT.md (RealOutcomes full GoTrue stop — not applicable to Onset)


Executive summary

Gate E for Onset is verification + documentation, not container teardown. The clinic portal authenticates exclusively via auth.last1.id and the encrypted clinic_last1_session cookie (Gates B–D). supabase-auth remains running on VM 119 for iOS/patient GoTrue until App Store release (Q4 lock). Kong /auth/v1/* routes unchanged (14 auth-v1 services in kong.yml).

E-3 outcome: Real Sign in with Apple on TestFlight against R940 GoTrue (onset-db.tailc3bbdc.ts.net over Tailscale, key TU6S85XABQ) — not just an endpoint probe. This proves the iOS-on-R940 auth path and de-risks T-5.

Clinic GoTrue login path: removed (no browser signInWith* / GoTrue session cookies).
Remaining clinic GoTrue touchpoints: /patients/new client bootstrap (supabase.auth.getUser) — deferred; plus server-side auth.admin.* on dormant signup/team paths.


1. What Gate E did (Onset vs RealOutcomes)

Action RealOutcomes Gate E Onset Gate E
Stop supabase-auth Yes No — explicitly forbidden
Remove Kong/Envoy /auth/v1/* Yes No — iOS depends on routes
Confirm clinic uses Last1 ID only N/A (only product) Yes — audited deployed source on VM 118
Confirm iOS GoTrue path alive N/A Yes — health + token probe
Document dual-auth window N/A Yes — §4

No infrastructure changes executed. Stack state unchanged from post–Gate D.


2. Clinic portal GoTrue dependency audit

Source: /opt/onset/src on VM 118 (onset-clinic-app), merged PR #7 / Gate C deploy.

2.1 Clinic login/session (Last1 ID — no GoTrue)

Component Auth mechanism
Middleware clinic_last1_session cookie only (src/middleware.ts)
Login UI Last1 ID OIDC redirect (src/app/login/page.tsx)
Callback /api/auth/last1/callback → completeClinicAuth → session cookie
Portal SSR/API identity getClinicSessionFromCookies() / service role
MFA UI Stub card — "managed by Last1 ID" (owner-mfa-card.tsx)

2.2 Browser-side GoTrue calls (clinic portal)

File Call Gate E disposition
(portal)/patients/new/page.tsx supabase.auth.getUser() GAP — deferred (only active clinic browser GoTrue call)
lib/clinic-mfa.ts supabase.auth.mfa.* Dead code — zero imports in deployed tree

2.3 Server-side GoTrue admin API (not clinic login)

These use service-role auth.admin.* against local GoTrue/Postgres — not browser practitioner login. Signup/team flows were stubbed/deferred in Gate B; they do not participate in Ryan's Last1 clinic login path.

File API Notes
api/clinic/register/route.ts auth.admin.createUser New owner signup deferred
api/clinic/team/route.ts auth.admin.inviteUserById, getUserById Team invite deferred
lib/clinic-data-lifecycle.ts auth.admin.getUserById, updateUserById Account lifecycle admin

2.4 Intentional non-clinic GoTrue JWT path

File Call Consumer
api/protocols/v2/[patientId]/latest/route.ts supabase.auth.getUser() iOS patient Bearer JWT — must stay on GoTrue until T-5

2.5 Secondary anomaly (not supabase.auth, but post–Gate B risk)

File Pattern Risk
(portal)/patients/[id]/notes-editor.tsx Browser anon createClient() → direct .from() No GoTrue session; RLS may block writes
(portal)/templates/template-actions.tsx Same Same

Gate E does not fix these. Track under portal SSR migration backlog (service-role API routes), separate from GoTrue retirement.


3. iOS GoTrue path — confirmed intact

VM 119 (192.168.1.102):

Check Result
supabase-auth container running / healthy
Kong auth-v1 routes in kong.yml 14 services present
GET /auth/v1/health (no apikey) 401 — Kong gateway (route exists)
GET /auth/v1/health (+ apikey) 200 — GoTrue v2.189.0
POST /auth/v1/token?grant_type=password for hello@unicornryda.com 400 invalid_credentials (probe password — proves token endpoint live)
hello@unicornryda.com in auth.users present — 26b42005-344b-4f4b-9db7-58c19c3ca037

Note: RealOutcomes post-retirement showed 401 on bare /auth/v1/health because routes were removed. Onset 401 without apikey + 200 with apikey means GoTrue is UP, not retired.


4. Cross-stack auth state (this window)

┌─────────────────────────┬──────────────────────────┬─────────────────────────┐
│ Surface                 │ Identity                 │ Auth backend            │
├─────────────────────────┼──────────────────────────┼─────────────────────────┤
│ Clinic portal (VM 118)  │ curryrg@gmail.com →      │ auth.last1.id (OIDC)    │
│                         │ id_token.sub = practitioner.user_id                  │
│                         │ session: clinic_last1_session cookie                   │
├─────────────────────────┼──────────────────────────┼─────────────────────────┤
│ iOS / patient app       │ hello@unicornryda.com +  │ **R940 GoTrue proven**  │
│ (Release / App Store)   │ demo patients            │ Hosted prod until T-4/  │
│                         │                          │ T-5 cutover             │
│                         │                          │ (emxrmjysvxeboavhatry)  │
├─────────────────────────┼──────────────────────────┼─────────────────────────┤
│ iOS Onset Staging       │ TestFlight / Debug       │ **Hosted staging**      │
│ (xcconfig default)      │                          │ lzpyfohgfdohrtlamzek    │
│                         │                          │ (reverted post–Gate E)  │
├─────────────────────────┼──────────────────────────┼─────────────────────────┤
│ Edge Functions          │ Service role + optional  │ VM 119 stack            │
│                         │ user JWT (GoTrue)        │                         │
├─────────────────────────┼──────────────────────────┼─────────────────────────┤
│ `/api/protocols/v2/*`   │ Patient GoTrue JWT       │ Local GoTrue (iOS path) │
│ patient branch          │                          │                         │
└─────────────────────────┴──────────────────────────┴─────────────────────────┘

Gate E proof path (temporary, now reverted): Onset Staging TestFlight was pointed at R940 (onset-db.tailc3bbdc.ts.net) for E-3 device verification only. Staging.xcconfig reverted to hosted on closeout so staging builds again match docs/expectation.

Coexistence rule: Clinic Last1 sessions never call local GoTrue for login. iOS never calls auth.last1.id for patient auth in this window. Both stacks share one Postgres (auth.users + practitioner FKs).

T-5 de-risk: E-3 proved end-to-end iOS → R940 GoTrue → Apple id_token exchange. App Store cutover is now an xcconfig/host swap, not an unknown auth integration.

Full GoTrue retirement: T-5 only, after iOS App Store ships on R940 (Q4 lock). See ONSET_MIGRATION_PLAN.md.


5. Automated verification (agent)

Test Result
supabase-auth running PASS
/auth/v1/health + apikey → 200 PASS
hello@unicornryda.com token endpoint PASS (400 invalid_credentials)
Edge: practitioner-notifications PASS (200)
Edge: last1-connect-assertion PASS (401 reachable — expected without valid assertion)
GET https://onset-app.tailc3bbdc.ts.net/login 200
GET https://auth.last1.id/.well-known/openid-configuration 200

Script: scripts/onset/gate-e-verify-partial-gotrue.sh (run on VM 119)


6. Manual verification (Ryan)

# Test Result
E-1 Clinic Last1 login (curryrg@gmail.com) PASS (Gate D repeat)
E-2 GoTrue health + apikey → 200 PASS
E-3 iOS Sign in with Apple as hello@unicornryda.com PASS — real device auth on R940 GoTrue (see §6.1)
E-4 supabase-auth still Up (healthy) on VM 119 PASS

6.1 E-3 — real Apple Sign-In pass (2026-08-29)

Ryan confirmed Onset Staging TestFlight Sign in with Apple as hello@unicornryda.com.

Item Value
Build Onset Staging (Release-Staging), 1.2.22 build 7
Backend (proof window) R940 onset-db.tailc3bbdc.ts.net over Tailscale
Apple key TU6S85XABQ (Apple Auth Key TU6S85XABQ.p8) in BWS + R940 GoTrue
GoTrue settings apple: true, anonymous_users: true
Identity hello@unicornryda.com — apple row restored (26b42005-344b-4f4b-9db7-58c19c3ca037)

Stronger than endpoint probe: Full iOS → Apple → GoTrue id_token → session path verified on device.

6.2 E-3 fix history (blocker → resolved)

Ryan initially reported Apple Sign-In failure during E-3.

Check R940 onset-db (192.168.1.102:8000) Hosted prod (emxrmjysvxeboavhatry)
/auth/v1/settings → apple was false → fixed true true
/auth/v1/settings → anonymous_users was false → fixed true true

Root cause: R940 stack provisioned in T-2 without Apple OAuth secrets (hosted-only at the time). Not a Gate E regression.

Fix applied:

Step Status
BWS ONSET_DB_PROD_APPLE_* (team, key id, services id, PEM) Created — key TU6S85XABQ via push-onset-apple-bws.py
VM 119 configure-onset-gotrue-apple.sh PASS
hello@unicornryda.com auth.identities repair Applied — gate-e-repair-hello-apple-identity.sql
Device re-test PASS — Ryan sign-off 2026-08-29

Prior doc referenced key RV26UG9967 from hosted config; Gate E rotation uses TU6S85XABQ (see §9).


7. Gate E closeout — temporary state reverted (2026-08-30)

Gate E required a temporary R940 pointer in Staging.xcconfig for E-3 device proof. Leaving it would make staging silently authenticate against R940 while docs say hosted — the drift pattern that caused confusion twice this week. Reverted before Ryan formal sign-off.

Item Action Evidence
Staging.xcconfig → hosted Reverted onset-ios 9825d3f — SUPABASE_HOST = lzpyfohgfdohrtlamzek.supabase.co, publishable anon key restored
GitHub secret APPLE_PRIVATE_KEY Removed Temp secret added 2026-08-30 during aborted hosted push attempt; deleted on closeout
R940 GoTrue Apple config Retained BWS + VM 119 — required for T-5; not a staging xcconfig concern

Current expectation: Onset Staging / Debug builds → hosted staging (lzpyfohgfdohrtlamzek). App Store Release → hosted prod (emxrmjysvxeboavhatry) until T-4/T-5 cutover. R940 auth path is proven, not default.


8. Gate E disposition summary

Question Answer
Clinic GoTrue login removed? Yes — Last1 ID + clinic_last1_session only
Clinic GoTrue dependency fully zero? No — /patients/new getUser() gap deferred
iOS GoTrue path intact? Yes — health/token UP; Apple provider enabled on R940
E-3 Apple Sign-In on R940? Yes — device pass (not endpoint-only)
iOS-on-R940 auth proven? Yes — de-risks T-5 App Store cutover
supabase-auth stopped? No — by design
Kong /auth/v1/* removed? No — by design
Temporary xcconfig / GH secret drift? Cleared — §7
Anomalies notes-editor/template-actions anon RLS risk; dead clinic-mfa.ts; deferred register/team admin API

9. Apple key rotation vs GitGuardian incidents

These are separate secret classes. Do not conflate Apple Sign-In keys with Supabase JWT gg incidents.

Secret Key / incident Gate E action GG status
Apple Sign-In (.p8) TU6S85XABQ (new) replaces prior RV26UG9967 Loaded into BWS + R940 GoTrue for E-3 Not a GG incident — Apple keys are not in onset-ios repo
Supabase JWT (prod) GG 29340466 — Production.xcconfig Unchanged — still hosted prod anon key TRIGGERED — RESOLVE at T-5 when R940 prod keys ship in App Store
Supabase JWT (staging) GG 34103515 — Staging.xcconfig Unchanged — reverted to hosted staging publishable key TRIGGERED — RESOLVE when hosted staging deleted at T-5

TU6S85XABQ does not close GG 29340466 or 34103515. Those track Supabase anon JWTs in xcconfig, not Apple .p8 keys.

Apple Developer action: Confirm RV26UG9967 is revoked in Apple Developer → Keys if not already done when TU6S85XABQ was issued. R940 GoTrue and BWS now use TU6S85XABQ only. Hosted prod Apple config was not updated during Gate E (R940 was the test target); update hosted when prod Release cutover is planned.


10. Unblocked after Gate E pass

Gate Work
F T-3 closeout report — clinic auth unification complete for portal; iOS GoTrue carry documented; T-5 cutover plan inherits proven R940 iOS auth path

END Gate E report