Skip to main content
Last updated: 2026-05-31 · Staleness marker: [2026-05] Encore OS supports two distinct, complementary WebAuthn features. They use different Supabase APIs and different enablement switches — do not conflate them.
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 for localhost, 127.0.0.1, [::1].
Equivalent Management API call:
Requires @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:
Manual smoke test in Chrome: DevTools → WebAuthn tab → “Enable virtual authenticator environment” → add a passkey in Security settings → sign out → Sign in with a passkey.

References