Skip to content

MFA

Overview

JustIAM supports two MFA methods:

Method Description
TOTP Time-based One-Time Passwords (RFC 6238) — works with any authenticator app (Google Authenticator, Authy, 1Password, etc.)
Passkey FIDO2/WebAuthn hardware or platform authenticators (YubiKey, Touch ID, Face ID, Windows Hello)

MFA policy

The global MFA policy is configured in Settings → MFA Policy.

Policy value Behaviour
disabled MFA is never required
any Any enrolled MFA method is required at login
otp TOTP specifically required
passkey Passkey specifically required

Individual applications can override the global policy — see application MFA policy.

For dynamic, per-login MFA decisions based on user attributes or token claims, see MFA Selector Script.


Enrollment enforcement

Setting MFA Enforce Enrollment (mfa_enforce_enrollment = true) blocks every login until the user has at least one MFA method enrolled, regardless of the MFA policy value.

When a user logs in without any enrolled method and enforcement is active, JustIAM returns a mfa_enrollment_required response with an enrollment token. The user is guided through enrollment before completing login.


Re-authentication interval

mfa_reauth_interval_minutes (default 0, disabled): controls how often users must re-verify MFA within an active SSO session.

Value Behaviour
0 (default) MFA is verified once per session. After the first successful MFA challenge, subsequent OIDC and SAML flows in the same session skip the MFA step.
> 0 MFA is re-prompted if the user's last verification was more than N minutes ago, even if the SSO session is still valid.

This is useful for sensitive applications where you want to ensure the user recently verified their identity.


TOTP enrollment (self-service)

  1. Profile → MFA → Set up Authenticator App
  2. Scan the QR code with your authenticator app
  3. Enter the 6-digit code to confirm enrollment

API:

POST /api/v1/mfa/totp/enroll       # Returns: { secret, qr_code_uri }
POST /api/v1/mfa/totp/confirm       # Body: { code: "123456" }

Passkey enrollment (self-service)

  1. Profile → MFA → Register Passkey
  2. Your browser / device prompts for biometric or security key
  3. Optionally name the credential (e.g., "MacBook Touch ID")

API:

POST /api/v1/mfa/passkey/register/begin   # Returns WebAuthn challenge
POST /api/v1/mfa/passkey/register/finish?session=<token>

Multiple passkeys can be registered per account.


Managing enrolled methods

Action UI API
Remove TOTP Profile → MFA → Remove DELETE /api/v1/mfa/totp
List passkeys Profile → MFA GET /api/v1/mfa/passkeys
Rename passkey Profile → MFA → edit PATCH /api/v1/mfa/passkeys/{id}
Remove passkey Profile → MFA → remove DELETE /api/v1/mfa/passkeys/{id}

MFA at login

When MFA is required:

  1. POST /api/v1/auth/login returns:
    {
      "status": "mfa_required",
      "mfa_token": "<challenge_token>",
      "mfa_methods": ["totp", "passkey"]
    }
    
  2. Client presents the MFA challenge UI.
  3. User submits TOTP code: POST /api/v1/auth/mfa/totp { mfa_token, code }
    Or starts passkey: POST /api/v1/auth/mfa/passkey/beginPOST /api/v1/auth/mfa/passkey/finish
  4. On success, a full JWT is returned.

MFA allowed methods

The mfa_allowed_methods setting (comma-separated, default totp,passkey) controls which methods users may enroll. Set to totp to disable passkey enrollment.


WebAuthn configuration

The WebAuthn Relying Party ID and origin are derived from OIDC_ISSUER. Ensure that the domain in OIDC_ISSUER matches the origin from which users access JustIAM, or passkey registration and authentication will fail.


Trusted devices

After a successful MFA verification, JustIAM can mark the current browser as trusted for a configurable number of days. A trusted device skips the MFA challenge on subsequent logins — the user still authenticates with username and password, but the second factor is not required until the trust period expires.

Enabling trusted devices

Configure the duration in Settings → MFA → Trusted Device Duration (days) or set trusted_device_duration_days directly. A value of 0 (default) disables the feature entirely.

Setting key Description
trusted_device_duration_days Number of days a device trust is valid. 0 = disabled.

User experience

  1. After passing MFA at login, JustIAM displays a "Trust this device?" prompt.
  2. The user can optionally name the device (e.g. "Work laptop") and click Trust this device.
  3. JustIAM stores the trust record and sets an idp_device httpOnly cookie in the browser (Secure, SameSite=Strict) valid for the configured duration.
  4. On subsequent logins from the same browser, the cookie is sent automatically, MFA is skipped, and the last_seen_at timestamp is updated.
  5. Users can review and revoke trusted devices at any time under Profile → Trusted Devices.

API

Method Endpoint Description
POST /api/v1/me/devices Confirm trust for the current device using the token from the login response
GET /api/v1/me/devices List all trusted devices for the authenticated user
DELETE /api/v1/me/devices/{id} Revoke a specific trusted device

After a successful MFA login, the login response includes a trust_device_token:

{
  "token": "<jwt>",
  "trust_device_token": "<trust-token>"
}

Pass the trust_device_token when confirming trust:

POST /api/v1/me/devices
Authorization: Bearer <jwt>
Content-Type: application/json

{
  "token": "<trust-token>",
  "name": "Work laptop"
}