Skip to content

[auth 5] Support brokered browser OAuth on iOS and Android #193

Description

@artiphishle

Roadmap: #188

Respect the [auth] roadmap first and the AGENTS.md file of every repository touched.

Previous roadmap step

[auth 4] (#192) establishes canonical enabled targets, stable native identifiers/schemes, environment overlays and platform-aware provider setup requirements. This issue uses that foundation to make the existing brokered OAuth architecture work on real iOS and Android development builds without native provider SDKs.

Repository impact

Likely:

  • ankhorage/studio
  • ankhorage/supabase-auth
  • ankhorage/contracts only if neutral transport contracts are incomplete
  • ankhorage/infra
  • ankhorage/expo-runtime / generated app config ownership
  • ankhorage/ankh for readiness diagnostics

Goal

Support Google and other brokered OAuth providers on iOS and Android through the secure system authentication browser, the configured Auth backend and a generated app deep link.

Initial Google credentials remain:

Google Web Client ID
Google Web Client Secret

No Google iOS/Android Client IDs and no provider-native npm package are required in this issue because GoTrue/Auth backend remains the Google OAuth client.

Canonical flow

generated native app
  -> AuthOAuthAdapter.startAuthorization()
  -> WebBrowser.openAuthSessionAsync()
  -> Auth backend authorize endpoint
  -> provider authorization
  -> Auth backend provider callback
  -> generated app scheme://auth/callback?code=...
  -> AuthOAuthAdapter.completeAuthorization()
  -> normalized AuthSession

Requirements

Generated deep links

  • derive callback URI from the stable enabled target scheme from [auth 4];
  • use the configured Auth callback route, not a provider-specific route;
  • register the scheme and native linking configuration through canonical Expo app/runtime planning;
  • iOS and Android may share a stable app scheme where valid, but ownership and collisions must be validated;
  • do not hardcode myapp:// or one example project slug.

Native transport

  • use Expo/system authentication session, not embedded WebView;
  • openAuthSessionAsync is Native-only after [auth 1];
  • handle success, user cancellation, browser dismissal and transport failure through neutral result contracts;
  • callback code exchange remains PKCE-based in the Auth adapter;
  • do not extract access/refresh tokens from URL fragments;
  • do not call setSession with provider tokens from generated UI.

Auth backend/Infra

  • include enabled native callback URIs in GoTrue redirect allowlist;
  • preserve the exact provider-to-GoTrue callback registered in Google;
  • environment-specific local native callbacks are deterministic;
  • Auth runtime rollout uses [auth 2] reconciliation.

Provider neutrality

The generated runtime invokes only:

authAdapter.oauth.startAuthorization(...)
authAdapter.oauth.completeAuthorization(...)

No Supabase, Google, GitHub or Apple branching belongs in the UI transport except provider ID/configuration passed through the contract.

Development build requirements

Document and validate that native OAuth requires an actual development/native build where required, not an unsupported Expo Go assumption.

Studio/Doctor should show the exact callback scheme and current readiness.

Likely files

Studio/generator, non-exhaustive:

src/host/layout/templates/auth/oauth.ts
src/host/layout/templates/auth/callback.ts
src/host/orchestrator/templates.ts
src/host/layout/layoutGenerator.test.ts
src/host/oauthFixtureConsumer.smoke.test.ts

Supabase Auth:

src/oauth.ts
src/oauth.test.ts

Infra/Expo Runtime/Ankh paths must be identified from current scheme/deep-link ownership.

Phases

Phase 1 — generated native callback and linking plan

Generate stable target-aware deep-link callback configuration through canonical platform/runtime planning.

Phase 2 — native system-browser completion

Harden the transport/completion lifecycle for iOS and Android using the shared neutral adapter contract.

Phase 3 — development-build and device smoke validation

Add deterministic automated coverage plus documented/manual real-device or simulator smoke steps without requiring provider secrets in CI.

Tests

Cover at minimum:

  • iOS callback URI derivation from configured target scheme;
  • Android callback URI derivation from configured target scheme;
  • disabled native platform produces no callback/config;
  • Native branch uses openAuthSessionAsync and Web branch does not;
  • success callback exchanges PKCE code once;
  • cancel/dismiss/transport failure cleanup;
  • GoTrue allowlist includes enabled native callbacks only;
  • generated app config registers required schemes;
  • provider configuration remains one Web Client ID/Secret for brokered Google OAuth;
  • no token-fragment extraction or UI-owned Supabase session mutation;
  • Doctor reports development-build/deep-link readiness.

Acceptance criteria

  1. Brokered OAuth works on iOS and Android development builds.
  2. Native callbacks use stable generated app schemes.
  3. The same Web Google Client ID/Secret can serve Web/iOS/Android for this transport.
  4. Native flow uses the system authentication browser, never an embedded WebView.
  5. PKCE completion remains adapter-owned and provider-neutral.
  6. Cancel/dismiss/failure outcomes recover cleanly.
  7. Infra allowlists only enabled native callbacks.
  8. No provider-native SDK dependency is introduced.
  9. Studio/Doctor surfaces exact native callback/readiness information.
  10. Behavior-focused tests, package releases/changesets and full validation pass.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions