Passkeys are bound to the Relying Party (RP) ID. Changing the RP ID invalidates every existing passkey. Pick it carefully and keep it stable.
1. Phase 4 — Passwordless passkeys
1a. Server config
The canonical client (src/integrations/supabase/client.ts) is an
auto-generated, do-not-edit file, so the experimental opt-in lives in a
dedicated client at src/platform/auth/passkey/passkey-client.ts (distinct
storage key; sessions are bridged to the main client). No app code change is
needed to enable passkeys — only the Supabase project config below.
Option A — supabase/config.toml (local dev & branch deploys). This file
is write-protected in this repo; add the following by hand (or via the
Dashboard/Management API for hosted projects):
[auth.webauthn] is required whenever auth.passkey.enabled = true.
Option B — Dashboard / Management API (hosted/production). In the
Dashboard: Authentication → Passkeys → Enable Passkey authentication, then
set:
- Relying Party Display Name — e.g.
Encore OS - Relying Party ID — bare domain, no scheme/port/path (e.g.
app.example.com) - Relying Party Origins — comma-separated HTTPS origins (≤ 5); each
hostname must equal or be a subdomain of the RP ID
(e.g.
https://app.example.com). HTTPS required except forlocalhost,127.0.0.1,[::1].
@supabase/supabase-js >= 2.105 (we run ^2.105.3). Registering a
passkey requires a confirmed, non-anonymous, signed-in user; SSO and anonymous
users cannot register passkeys.
1b. Where users see it
- Add / manage: Settings → Security → Passwordless sign-in card.
- Sign in: the login screen shows Sign in with a passkey (only on WebAuthn-capable browsers).
2. Phase 3 — WebAuthn second factor (MFA)
The Supabase API rejects[auth.mfa.web_authn] enroll_enabled = true via
CLI/config push, so enable it in the Dashboard → Authentication → MFA →
WebAuthn (toggle enroll + verify). Until then, “Add a passkey” in the MFA
card fails at runtime with a sanitized error. No RP config is required beyond
the project’s Site URL.
Users add it under Settings → Security → Multi-Factor Authentication →
Passkeys, and are prompted for it at the MFA challenge after entering their
password.
3. Testing
Unit (no backend)
End-to-end (real WebAuthn ceremony, virtual authenticator)
tests/e2e/platform/pf-79-passkeys.spec.ts drives the real ceremonies with a
CDP virtual authenticator (no physical device). The register → sign-in
loop needs passkeys enabled on the target project with an RP origin matching
the test origin, so it is opt-in:
References
- Supabase passkeys guide: https://supabase.com/docs/guides/auth/passkeys (
#clifor config) - Supabase MFA guide: https://supabase.com/docs/guides/auth/auth-mfa
src/platform/auth/passkey/(Phase 4),src/platform/auth/components/webauthn-mfa.ts(Phase 3)