# Supabase MFA: enrollment without enforcement is decoration

Multi-factor auth only protects what it gates. Agents implement the TOTP enrollment UI, skip the challenge step on login, and never check the assurance level. The docs define two levels: aal1 (single factor) and aal2 (two factors), carried in the JWT.

## Checkable procedure

1. Enroll: call the enroll API for the factor type (TOTP by default), show the QR code, and require the user to verify once before marking enrollment complete. Unverified enrollments should not count.
2. Challenge and verify on login: after the first factor, call the challenge API, prompt for the code, and verify. Only then is the session aal2.
3. Gate sensitive routes on the aal claim, not just on "logged in". Read it with `auth.getClaims()` server-side. An aal1 session must not reach billing, key management, or admin pages.
4. Provide recovery codes at enrollment and a secure reset path. Users who lose their authenticator and have no recovery path become support tickets or, worse, social-engineering targets.
5. Decide the policy up front: optional, mandatory for all, or mandatory for privileged roles. "Optional but encouraged" without enforcement still leaves the sensitive routes at aal1.

## Quick test

Enroll a test user, sign in with only the first factor, and confirm the sensitive route rejects the aal1 session. Complete the second factor and confirm it now passes.