Multi-factor auth
Limen supports two second factors, configurable per tenant:
- TOTP — a code from an authenticator app (Google Authenticator, 1Password, …).
- Email OTP — a one-time code sent to the user's email.
How MFA surfaces at login
When a tenant requires MFA, the first login attempt with a correct password does
not return a session. It returns 401 with a reason:
{
"code": "UNAUTHORIZED",
"message": "Multi-factor authentication required",
"details": { "reason": "mfa_required" }
}
Collect the user's second factor and retry the same login request with the code included:
curl -X POST https://api.limen.eu/v1/acme/auth/login \
-H "content-type: application/json" \
-d '{
"email": "you@acme.eu",
"password": "a-strong-password",
"totpCode": "123456"
}'
Use emailOtpCode instead of totpCode when the factor is email.
Requesting an email code
For email OTP, ask Limen to send the code before the user can enter it:
curl -X POST https://api.limen.eu/v1/acme/auth/request-email-otp \
-H "content-type: application/json" \
-d '{ "email": "you@acme.eu" }'
The code is delivered by email and is valid for a short window.
Enrolling TOTP
A user with no factor yet enrolls TOTP in two steps — begin enrollment to get a secret and otpauth URL (render it as a QR code), then verify a code from the authenticator to activate it:
# 1. begin — returns the shared secret + otpauth:// URI
curl -X POST https://api.limen.eu/v1/acme/auth/totp/initial-enroll \
-H "content-type: application/json" \
-d '{ "email": "you@acme.eu", "password": "a-strong-password" }'
# 2. verify — activate the factor with a code from the app
curl -X POST https://api.limen.eu/v1/acme/auth/totp/initial-verify \
-H "content-type: application/json" \
-d '{ "email": "you@acme.eu", "password": "a-strong-password", "totpCode": "123456" }'
TOTP secrets are stored with field-level AES-256-GCM encryption and key versioning — they are never persisted in plaintext.
The Console's account page renders the QR code and handles enrollment end-to-end — useful for admins who don't want to build the enrollment UI themselves.