Skip to main content

Multi-Factor Authentication (MFA)

MFA enrollment and verification are integrated into the login flow.

MFA Flow

Initial Login (MFA Not Enrolled)

When logging in for the first time or when MFA is not yet configured:

Request:

POST /api/login/local
{
"username": "admin",
"password": "password123"
}

Response (MFA Setup Required):

{
"mfaConfigs": [
{
"id": "totp",
"name": "Authenticator App",
"setupComponent": "totp-setup",
"qrCode": "data:image/png;base64,iVBORw0KGgo...",
"secret": "BASE32ENCODEDSECRET"
}
],
"loginTicket": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

The client should:

  1. Display the QR code for the user to scan
  2. Prompt user to enter verification code from authenticator app
  3. Submit code to complete setup

Complete MFA Setup

Request:

POST /api/login/local
{
"username": "admin",
"mfaConfig": {
"loginTicket": "jwt-from-previous-response",
"code": "123456"
}
}

Response (Setup Success):

{
"user": { ... },
"sid": "session-id",
"jwt": "jwt-token",
"wsToken": "ws-token",
"locale": "en-US",
"lang": "en"
}

Error Response:

{
"statusCode": 400,
"error": "Bad Request",
"message": "Invalid authenticator code"
}

Login with MFA Enabled

When MFA is already enrolled:

Step 1: Initial Login

POST /api/login/local
{
"username": "admin",
"password": "password123"
}

Response:

{
"loginTicket": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"verifyConfig": {
"component": "totp-verify"
}
}

Step 2: Verify MFA Code

POST /api/login/local
{
"username": "admin",
"mfaConfig": {
"loginTicket": "jwt-from-step-1",
"code": "654321"
}
}

Response (Success):

{
"user": { ... },
"sid": "session-id",
"jwt": "jwt-token",
"wsToken": "ws-token"
}

MFA Configuration

Tenant-Level Enablement

MFA must be enabled at the tenant level before users can enroll.

Check Available Authenticators:

Available authenticators are determined by:

  • Tenant configuration
  • Domain eligibility
  • Driver implementation

Supported Authenticator Types

TypeDescriptionSetup Component
totpTime-based One-Time Password (Google Authenticator, Authy, etc.)totp-setup

Login Ticket

The login ticket is a JWT token that maintains state between login steps:

Contains:

  • username - User attempting to log in
  • tenant - Tenant ID
  • domain - Authentication domain

Purpose:

  • Prove successful password authentication
  • Prevent replay attacks
  • Maintain security during MFA flow

Expiration:

  • Short-lived (typically 5-10 minutes)
  • Single-use

Pre-blocks in Login Flow

The login route includes these MFA-related pre-blocks:

  1. loginTicket - Verify login ticket if provided
  2. enabledAuthenticators - Check which MFA methods are enabled
  3. mfaEnabled - Determine if MFA is required
  4. activeAuthenticator - Check if user has enrolled MFA
  5. maybeCreateLoginTicket - Create login ticket after password auth
  6. maybeSetupAuthenticator - Provide setup instructions if not enrolled
  7. mfaValidate - Verify MFA code

MFA Management

Enrollment

Users enroll in MFA during the login process when:

  • MFA is enabled for the tenant
  • User has successfully authenticated with password
  • User has not yet enrolled

Unenrollment

MFA unenrollment is typically done through:

  • User settings endpoints (see User API documentation)
  • Admin override (for account recovery)

Recovery

If a user loses access to their MFA device:

  • Admin can disable MFA for the user
  • User must re-enroll on next login

Domain Eligibility

Not all authentication domains support MFA:

  • Local Domain: MFA supported
  • SSO/SAML: MFA handled by IdP
  • LDAP: May support MFA depending on configuration

The isDomainEligible() driver method determines if MFA can be used for a specific domain.


Security Considerations

Backup Codes

Consider implementing backup codes for account recovery:

  • Generate one-time use codes during enrollment
  • Store securely (hashed)
  • Allow use when primary MFA method unavailable

Rate Limiting

MFA verification should be rate-limited:

  • Prevent brute force attacks
  • Lock account after N failed attempts

Time Skew

TOTP codes have a time window:

  • Typically 30-second intervals
  • Allow 1-2 time steps of skew for clock differences
Security Best Practice

Always use HTTPS for MFA flows to prevent token interception. Login tickets and MFA codes should never be transmitted over unencrypted connections.

User Experience

The two-step MFA flow (password → code) provides better security than embedding the code in the initial login request, as it proves both factors separately.