OpenGate/ Docs

MFA API

Manage multi-factor authentication enrollment and verification.

On this page


TOTP Enrollment

Step 1 — Start enrollment

POST /api/mfa/totp/enroll
Authorization: Bearer <token>
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
http://localhost:8080/api/mfa/totp/enroll
{
"secret": "JBSWY3DPEHPK3PXP",
"qrCodeUri": "otpauth://totp/OpenGate:alice@example.com?secret=JBSWY3DPEHPK3PXP&issuer=OpenGate",
"enrollmentId": "enroll-uuid-123"
}

Display the qrCodeUri as a QR code. The user scans it with their authenticator app.

Step 2 — Confirm enrollment

POST /api/mfa/totp/confirm
Authorization: Bearer <token>
Content-Type: application/json
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/confirm

Response: 200 OK — MFA is now active.


TOTP Verification

During login when MFA challenge is issued:

POST /api/mfa/totp/verify
Content-Type: application/json
curl -X POST \
-H "Content-Type: application/json" \
-d '{ "userId": "usr_abc123", "code": "654321", "mfaToken": "<mfa_token>" }' \
http://localhost:8080/api/mfa/totp/verify

Response:

{ "verified": true }

Time tolerance

OpenGate accepts TOTP codes from the previous and next 30-second windows (±1 window tolerance) to account for clock drift.


Email OTP

POST /api/mfa/email-otp/send
Authorization: Bearer <token>

POST /api/mfa/email-otp/verify
Authorization: Bearer <token>
Content-Type: application/json
# Send OTP to user's verified email
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
http://localhost:8080/api/mfa/email-otp/send

# Verify the 6-digit code (valid 10 minutes)
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "code": "847291" }' \
http://localhost:8080/api/mfa/email-otp/verify

Backup Codes

POST /api/mfa/backup-codes/generate
Authorization: Bearer <token>
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 code is 8 characters, usable exactly once. Generate new codes to invalidate old ones.


Disable MFA

DELETE /api/mfa/totp
Authorization: Bearer <token>
curl -X DELETE \
-H "Authorization: Bearer $TOKEN" \
http://localhost:8080/api/mfa/totp

Response: 204 No Content

Admin can disable MFA for locked-out users

If a user loses their authenticator and all backup codes, an admin can call DELETE /admin/users/{userId}/mfa to disable MFA and allow password-only login.