Documentation Index
Fetch the complete documentation index at: https://mintlify.com/zitadel/zitadel/llms.txt
Use this file to discover all available pages before exploring further.
Multi-Factor Authentication (MFA) adds an additional layer of security by requiring users to provide two or more verification factors to access their accounts. ZITADEL supports multiple MFA methods including OTP, U2F, SMS, and email-based verification.
MFA Methods
ZITADEL supports the following multi-factor authentication methods:
Time-based One-Time Password (TOTP)
TOTP generates time-based codes using authenticator apps like:
- Google Authenticator
- Microsoft Authenticator
- Authy
- 1Password
- Any RFC 6238-compliant authenticator
Security Level: Second Factor
Implementation: RFC 6238 standard TOTP algorithm
Universal 2nd Factor (U2F)
Hardware security keys using the FIDO U2F standard:
- YubiKey
- Google Titan Security Key
- Other FIDO-compliant security keys
Security Level: Second Factor or Multi-Factor
Implementation: WebAuthn/FIDO2 protocol
OTP via SMS
One-time passwords delivered via SMS text message to the user’s registered phone number.
Security Level: Second Factor
Implementation: Requires SMS provider configuration (Twilio or custom webhook)
SMS-based OTP is less secure than TOTP or U2F due to potential SIM swapping attacks. Use for convenience but consider stronger methods for high-security scenarios.
OTP via Email
One-time passwords sent to the user’s registered email address.
Security Level: Second Factor
Implementation: Uses configured SMTP or email provider
MFA Configuration
Enabling MFA Methods
Configure which MFA methods are available through the Login Policy.
Via Console
Navigate to Login Policy
Go to Instance/Organization Settings > Login Policy
Configure Second Factors
In the Second Factors section, select available methods:
- TOTP (Time-based OTP)
- OTP Email
- OTP SMS
Configure Multi-Factors
In the Multi-Factors section, add additional factor options:
- U2F (Universal 2nd Factor)
Set MFA Policy
Choose MFA enforcement:
- Optional: Users can enable MFA voluntarily
- Required: All users must configure MFA (Force MFA)
- Required for Local Only: Only local accounts require MFA, not federated users
Via API
# Add TOTP as a second factor
curl -X POST https://$ZITADEL_DOMAIN/v2/settings/login_policy/second_factors \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "SECOND_FACTOR_TYPE_OTP"
}'
# Add U2F as a multi-factor
curl -X POST https://$ZITADEL_DOMAIN/v2/settings/login_policy/multi_factors \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "MULTI_FACTOR_TYPE_U2F"
}'
# Enable Force MFA
curl -X PUT https://$ZITADEL_DOMAIN/v2/settings/login_policy \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"forceMfa": true
}'
MFA Enforcement Modes
ForceMFA: When enabled, all users must configure at least one MFA method before they can complete authentication.
ForceMFALocalOnly: When enabled, only users authenticating with local credentials (username/password) must use MFA. Users authenticating via external identity providers are exempt.
// From internal/domain/policy_login.go
type LoginPolicy struct {
ForceMFA bool
ForceMFALocalOnly bool
SecondFactors []SecondFactorType
MultiFactors []MultiFactorType
// ...
}
Setting Up MFA Methods
TOTP Setup
User Initiates Setup
User navigates to account settings and selects “Add Authenticator App”
QR Code Generation
ZITADEL generates a QR code containing the TOTP secret
Scan with Authenticator
User scans the QR code with their authenticator app
Verify Setup
User enters the current TOTP code to verify the setup is working
Save Recovery Codes
ZITADEL provides recovery codes for account recovery if the device is lost
TOTP Configuration
The TOTP configuration is managed through MultifactorConfigs:
// From internal/domain/mfa.go
type MultifactorConfigs struct {
OTP OTPConfig
RecoveryCodes RecoveryCodesConfig
}
type OTPConfig struct {
Issuer string // Displayed in authenticator app
CryptoMFA crypto.EncryptionAlgorithm
}
U2F/WebAuthn Setup
User Initiates Registration
User selects “Add Security Key” in account settings
Insert Security Key
User inserts their U2F security key or prepares their device authenticator
Trigger Registration
Browser prompts for user interaction (touch security key button)
Complete Registration
ZITADEL stores the public key and associates it with the user account
Name the Key
User provides a friendly name for the security key (e.g., “YubiKey 5C”)
OTP SMS Setup
Configure SMS Provider
First, configure an SMS provider in ZITADEL (Twilio or custom webhook)
User Adds Phone Number
User enters their phone number in account settings
Verify Phone Number
ZITADEL sends a verification code via SMS
Complete Verification
User enters the code to verify phone ownership
Enable OTP SMS
OTP SMS is now available as an MFA method for the user
API Setup
# Add OTP SMS to a user
curl -X POST https://$ZITADEL_DOMAIN/v2/users/{userId}/otp_sms \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json"
# Remove OTP SMS
curl -X DELETE https://$ZITADEL_DOMAIN/v2/users/{userId}/otp_sms \
-H "Authorization: Bearer $ACCESS_TOKEN"
OTP Email Setup
Verify Email Address
User must have a verified email address on their account
Enable OTP Email
User enables OTP Email in account security settings
Test Delivery
ZITADEL sends a test code to verify email delivery
Complete Setup
User enters the test code to confirm setup
API Setup
# Add OTP Email to a user
curl -X POST https://$ZITADEL_DOMAIN/v2/users/{userId}/otp_email \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json"
# Remove OTP Email
curl -X DELETE https://$ZITADEL_DOMAIN/v2/users/{userId}/otp_email \
-H "Authorization: Bearer $ACCESS_TOKEN"
MFA Authentication Flow
When MFA is required, the authentication flow includes an additional verification step:
Primary Authentication
User provides primary credentials (username/password or passkey)
MFA Challenge
ZITADEL prompts for second factor based on user’s registered methods
User Selects Method
If multiple MFA methods are registered, user chooses which one to use
Provide Second Factor
User provides the second factor (TOTP code, U2F key, SMS code, etc.)
Verification
ZITADEL verifies the second factor
Session Creation
Successful MFA grants access and creates an authenticated session
MFA State Management
// From internal/domain/mfa.go
type MFAState int32
const (
MFAStateUnspecified MFAState = iota
MFAStateNotReady // MFA setup initiated but not completed
MFAStateReady // MFA fully configured and active
MFAStateRemoved // MFA was removed from account
)
Recovery Codes
Recovery codes provide a backup authentication method if users lose access to their MFA devices.
Generating Recovery Codes
When users enable MFA, ZITADEL generates a set of single-use recovery codes.
// From internal/domain/mfa.go
type RecoveryCodesConfig struct {
MaxCount int // Number of codes to generate
Format RecoveryCodeFormat // Format of codes
Length int // Length of each code
WithHyphen bool // Include hyphens for readability
}
const (
RecoveryCodeFormatUUID RecoveryCodeFormat = "uuid"
RecoveryCodeFormatAlphanumeric RecoveryCodeFormat = "alphanumeric"
)
Using Recovery Codes
Select Recovery Option
During MFA prompt, user selects “Use recovery code” option
Enter Code
User enters one of their saved recovery codes
Code Validation
ZITADEL validates and invalidates the used recovery code
Access Granted
User gains access and should set up MFA again or generate new recovery codes
Recovery codes are single-use. Once all recovery codes are consumed, users must generate new ones or risk account lockout if they lose their MFA device.
MFA Lifetime Settings
Control how long MFA verification remains valid:
Second Factor Check Lifetime
curl -X PUT https://$ZITADEL_DOMAIN/v2/settings/login_policy \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"secondFactorCheckLifetime": "43200s" // 12 hours
}'
Multi-Factor Check Lifetime
curl -X PUT https://$ZITADEL_DOMAIN/v2/settings/login_policy \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"multiFactorCheckLifetime": "43200s" // 12 hours
}'
MFA Init Skip Lifetime
Allow users to skip MFA setup for a period:
curl -X PUT https://$ZITADEL_DOMAIN/v2/settings/login_policy \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"mfaInitSkipLifetime": "2592000s" // 30 days
}'
Best Practices
Enforce MFA for Sensitive Operations: Always require MFA for privileged accounts (administrators, service accounts with elevated permissions).
Provide Multiple Options: Enable multiple MFA methods to accommodate different user preferences and scenarios.
Educate Users: Provide clear instructions and support documentation for MFA setup and usage.
Recovery Planning: Ensure users save recovery codes and understand the recovery process before they need it.
SMS Limitations: While convenient, SMS-based OTP is vulnerable to SIM swapping. For high-security applications, prefer TOTP or U2F.
SMS Provider Configuration
To use OTP SMS, configure an SMS provider:
Twilio Configuration
Notifications:
Providers:
Twilio:
SID: "your-twilio-account-sid"
Token: "your-twilio-auth-token"
SenderNumber: "+1234567890"
Custom SMS Webhook
Alternatively, configure a custom webhook for SMS delivery:
Notifications:
Providers:
Webhook:
Enabled: true
URL: "https://your-sms-provider.com/send"
Headers:
Authorization: "Bearer your-token"
Troubleshooting
MFA Setup Fails
Check time synchronization: TOTP requires accurate system time (use NTP)
Verify QR code: Ensure the QR code is scanned correctly
Browser compatibility: Confirm WebAuthn support for U2F setup
MFA Verification Fails
Time drift: TOTP codes expire every 30 seconds; ensure timely entry
Used recovery code: Recovery codes are single-use only
SMS not received: Check SMS provider configuration and phone number validity
U2F timeout: User must interact with security key within the timeout period
Account Lockout
Use recovery codes: Enter a saved recovery code to regain access
Administrator intervention: Admins can disable MFA for locked-out users
Account recovery flow: Implement proper account recovery procedures
API Reference
Key MFA-related API endpoints:
Add TOTP
POST /v2/users/{userId}/totp
Verify TOTP
POST /v2/users/{userId}/totp/verify
Add OTP SMS
POST /v2/users/{userId}/otp_sms
Add OTP Email
POST /v2/users/{userId}/otp_email
Register U2F Token
POST /v2/users/{userId}/u2f
List User’s MFA Methods
GET /v2/users/{userId}/authentication_methods
See the User Service API for complete documentation.