Multi-Factor Authentication
OpenGate IAM provides MFA via the dedicated opengate-mfa-service (port 8086). It supports TOTP, Email OTP, and backup codes.
On this page
Supported Methods
| Method | Security Level | Description |
|---|---|---|
| TOTP | ๐ High | Time-based OTP โ Google Authenticator, Authy, 1Password |
| Email OTP | ๐ Medium | 6-digit code delivered to verified email |
| Backup Codes | ๐ Recovery | 10 one-time recovery codes โ always generate these |
MFA Login Flow
When mfaRequired: true is set on a realm:
Client Auth Service MFA Service
โ โ โ
โ 1. POST credentials โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโบโ โ
โ โ 2. Password valid โ
โ 3. { status: โ โ
โ "MFA_REQUIRED", โ โ
โ mfa_token } โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ 4. POST /api/mfa/ โ โ
โ totp/verify โ โ
โ { code, mfa_token } โโโโโโโโโโโโโโโโโโโโโโโโโโบโ
โ โ โ 5. Verify TOTP
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ 6. Issue access_token โ
โโโโโโโโโโโโโโโโโโโโโโโโโโ โ
TOTP Enrollment
# Step 1 โ Initiate enrollment
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
http://localhost:8080/api/mfa/totp/enrollResponse:
{
"secret": "JBSWY3DPEHPK3PXP",
"qrCodeUri": "otpauth://totp/OpenGate:alice@example.com?secret=JBSWY3DPEHPK3PXP&issuer=OpenGate",
"enrollmentId": "enroll-uuid-123"
}# Step 2 โ Confirm with first 6-digit code from authenticator app
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "enrollmentId": "enroll-uuid-123", "code": "123456" }' \
http://localhost:8080/api/mfa/totp/confirmTOTP implementation
OpenGate uses a custom HMAC-SHA1 RFC 6238 implementation with ยฑ1 time-window tolerance (30-second windows). Compatible with Google Authenticator, Authy, and any RFC 6238-compliant app.
Email OTP
# Trigger email OTP (sends 6-digit code to verified email)
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
http://localhost:8080/api/mfa/email-otp/send
# Verify the code (valid for 10 minutes)
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "code": "847291" }' \
http://localhost:8080/api/mfa/email-otp/verifyBackup Codes
# Generate 10 one-time backup codes
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
http://localhost:8080/api/mfa/backup-codes/generate{
"codes": [
"AAAA-BBBB", "CCCC-DDDD", "EEEE-FFFF",
"GGGG-HHHH", "IIII-JJJJ", "KKKK-LLLL",
"MMMM-NNNN", "OOOO-PPPP", "QQQQ-RRRR",
"SSSS-TTTT"
]
}Each backup code can only be used once
Store backup codes in a password manager. Once all 10 are used you must regenerate. If lost, an admin can disable MFA for the account.
Enforce MFA per Realm
curl -X PUT \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "mfaRequired": true }' \
http://localhost:8080/api/realms/my-realmWhen enabled, every user in the realm must complete MFA before receiving tokens.