Multi-factor authentication against Supabase Auth.
Supports TOTP (authenticator apps), phone (SMS / WhatsApp) and WebAuthn
factors. Every function acts on behalf of the signed-in user identified
by access-token — the JWT from an active session.
The usual TOTP flow:
(require '[supabase.auth.mfa :as mfa])
;; 1. enroll — body carries the QR code / secret to show the user
(mfa/enroll client token {:factor-type "totp" :friendly-name "authenticator"})
;; 2. user scans the QR and types the 6-digit code
(mfa/challenge-and-verify client token factor-id "123456")
Phone and WebAuthn factors need the explicit challenge + verify
round-trip since the response arrives out of band.
Each function returns {:status :body :headers} on success or an anomaly
map on failure. See https://supabase.com/docs/guides/auth/auth-mfa
Multi-factor authentication against Supabase Auth.
Supports TOTP (authenticator apps), phone (SMS / WhatsApp) and WebAuthn
factors. Every function acts on behalf of the signed-in user identified
by `access-token` — the JWT from an active session.
The usual TOTP flow:
(require '[supabase.auth.mfa :as mfa])
;; 1. enroll — body carries the QR code / secret to show the user
(mfa/enroll client token {:factor-type "totp" :friendly-name "authenticator"})
;; 2. user scans the QR and types the 6-digit code
(mfa/challenge-and-verify client token factor-id "123456")
Phone and WebAuthn factors need the explicit `challenge` + `verify`
round-trip since the response arrives out of band.
Each function returns `{:status :body :headers}` on success or an anomaly
map on failure. See https://supabase.com/docs/guides/auth/auth-mfa(challenge client access-token factor-id)(challenge client access-token factor-id params)Creates a challenge for the factor factor-id. The returned body carries
the challenge :id to pass to verify.
params is factor-type specific and optional:
:channel ("sms" or "whatsapp"):webauthn map (rp_id, optional rp_origins)(challenge client "<access-token>" "<factor-id>")
(challenge client "<access-token>" "<factor-id>" {:channel "sms"})
Creates a challenge for the factor `factor-id`. The returned body carries
the challenge `:id` to pass to `verify`.
`params` is factor-type specific and optional:
* TOTP — none
* phone — `:channel` (`"sms"` or `"whatsapp"`)
* WebAuthn — `:webauthn` map (`rp_id`, optional `rp_origins`)
## Example
(challenge client "<access-token>" "<factor-id>")
(challenge client "<access-token>" "<factor-id>" {:channel "sms"})(challenge-and-verify client access-token factor-id code)Challenge + verify in one call, for TOTP factors where the code is already at hand. Phone and WebAuthn factors need the separate calls.
(challenge-and-verify client "<access-token>" "<factor-id>" "123456")
Challenge + verify in one call, for TOTP factors where the code is
already at hand. Phone and WebAuthn factors need the separate calls.
## Example
(challenge-and-verify client "<access-token>" "<factor-id>" "123456")(enroll client access-token params)Enrolls a new MFA factor for the user. The factor starts unverified;
complete a challenge + verify round-trip to activate it.
client — Supabase clientaccess-token — the user's access tokenparams:
:factor-type — "totp", "phone" or "webauthn" (required):friendly-name — label shown in factor lists:issuer — TOTP issuer domain (totp only):phone — E.164 phone number (required for phone factors)For TOTP the response body carries :totp with the QR code SVG, secret
and provisioning URI to present to the user.
(enroll client "<access-token>" {:factor-type "totp"})
Enrolls a new MFA factor for the user. The factor starts `unverified`;
complete a `challenge` + `verify` round-trip to activate it.
## Parameters
* `client` — Supabase client
* `access-token` — the user's access token
* `params`:
* `:factor-type` — `"totp"`, `"phone"` or `"webauthn"` (required)
* `:friendly-name` — label shown in factor lists
* `:issuer` — TOTP issuer domain (totp only)
* `:phone` — E.164 phone number (required for phone factors)
For TOTP the response body carries `:totp` with the QR code SVG, secret
and provisioning URI to present to the user.
## Example
(enroll client "<access-token>" {:factor-type "totp"})(get-authenticator-assurance-level client access-token)Returns the user's current and next possible authenticator assurance levels.
The current level and authentication methods come from the JWT claims
(decoded locally); the next achievable level requires the user's factor
list, so this makes one get-user call.
Returns {:current-level :next-level :current-authentication-methods}
on success — levels are "aal1" / "aal2", methods the raw amr
claim entries — or an anomaly on failure.
(get-authenticator-assurance-level client "<access-token>")
Returns the user's current and next possible authenticator assurance
levels.
* AAL1 — single factor (password, magic link, OAuth)
* AAL2 — at least one verified MFA factor was used
The current level and authentication methods come from the JWT claims
(decoded locally); the next achievable level requires the user's factor
list, so this makes one `get-user` call.
Returns `{:current-level :next-level :current-authentication-methods}`
on success — levels are `"aal1"` / `"aal2"`, methods the raw `amr`
claim entries — or an anomaly on failure.
## Example
(get-authenticator-assurance-level client "<access-token>")(list-factors client access-token)Lists the user's MFA factors, grouped for convenience.
On success the body is a map with:
:all — every factor, verified or not:totp / :phone / :webauthn — verified factors of that type(list-factors client "<access-token>")
Lists the user's MFA factors, grouped for convenience.
On success the body is a map with:
* `:all` — every factor, verified or not
* `:totp` / `:phone` / `:webauthn` — verified factors of that type
## Example
(list-factors client "<access-token>")(unenroll client access-token factor-id)Removes the factor factor-id from the user's account. Permanent.
(unenroll client "<access-token>" "<factor-id>")
Removes the factor `factor-id` from the user's account. Permanent.
## Example
(unenroll client "<access-token>" "<factor-id>")(verify client access-token factor-id challenge-id params)Verifies the challenge challenge-id for factor factor-id. On success
the body carries a new session with elevated assurance level (AAL2).
params is factor-type specific:
{:code "123456"}{:webauthn {...credential response...}}(verify client "<access-token>" "<factor-id>" "<challenge-id>"
{:code "123456"})
Verifies the challenge `challenge-id` for factor `factor-id`. On success
the body carries a new session with elevated assurance level (AAL2).
`params` is factor-type specific:
* TOTP / phone — `{:code "123456"}`
* WebAuthn — `{:webauthn {...credential response...}}`
## Example
(verify client "<access-token>" "<factor-id>" "<challenge-id>"
{:code "123456"})cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |