Two-step sign-in and passkeys

Authenticator-app codes for any user, the two-step requirement for super admins, and passkey sign-in.

Two-step sign-in (TOTP)

Every user can add an authenticator app in account settings. Both account settings pages pass enableMultiFactorAuth: true, and the local stack has TOTP enrolment and verification on ([auth.mfa.totp] in apps/web/supabase/config.toml). Turn the same on in your hosted Supabase project.

Once a user has a verified factor:

  • After the first sign-in step, apps/web/proxy.ts sends them to /auth/verify for a code before any app page loads.
  • The database enforces it too. public.is_mfa_compliant() returns false for a user who has a verified factor but whose session has not passed the second step, and restrictive policies in apps/web/supabase/schemas/13-mfa.sql apply it to 11 tables: accounts, memberships, role permissions, invitations, subscriptions and their items, orders and their items, billing customers, notifications and one-time tokens. A session that skipped the code cannot read that data, even through the API.

Super admins

The admin panel (/admin) is for users whose app_metadata.role is super-admin. app_metadata can only be set server-side, so a user cannot give themselves the role. public.is_super_admin() also returns false unless the session passed two-step sign-in (is_aal2()), so a super admin without a second factor has no admin access. To add one, see docs/admin/adding-super-admin.mdoc.

The tests super-admin.test.sql and super-admin-edge-cases.test.sql in apps/web/supabase/tests/database check both rules, including a user who tries to fake the role.

Passkeys

Passkeys are off by default. To turn them on:

  1. Set NEXT_PUBLIC_AUTH_PASSKEY=true.
  2. Enable WebAuthn in your Supabase project (Authentication, then Sign In / Providers) with your domain as the relying party. The local stack already has [auth.passkey] on, with rp_id = "localhost" and http://localhost:3000 as the origin.

With the flag on, the sign-in page shows a passkey button and users manage their passkeys in account settings.