shipanysaas
Documentation
Back
  • Getting started
    • Install and run
    • Project structure
    • Configuration
    • Commands
  • Coding agents
    • Agent skills
  • Authentication
    • Email sign-in
    • OAuth providers
    • Two-step sign-in and passkeys
  • Database
    • Migrations
    • Row-level security
    • Database tests
    • Reading and writing data
  • Features
    • Teams and invitations
    • Email
    • File uploads
    • Blog, docs and changelog
  • Billing
    • Stripe and Lemon Squeezy
    • Pricing plans
    • Webhooks
  • Live demo
  • 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.