Multi-Factor Authentication (MFA)
AuthFI supports TOTP-based MFA with backup codes. MFA can be enforced per-tenant, per-organization, or per-access-policy.
TOTP Enrollment
1. Enroll
POST /v1/acme/mfa/enroll
Authorization: Bearer <access_token> Response:
{
"factor_id": "factor-uuid",
"type": "totp",
"secret": "JBSWY3DPEHPK3PXP",
"uri": "otpauth://totp/AuthFI:alice@acme.com?secret=JBSWY3DPEHPK3PXP&issuer=AuthFI",
"qr_code": "data:image/png;base64,..."
} Display the QR code for the user to scan with Google Authenticator, Authy, or 1Password.
2. Verify
POST /v1/acme/mfa/verify
Authorization: Bearer <access_token>
{ "code": "123456" } On successful verification, AuthFI generates 10 backup codes returned in the response. These are shown once and should be saved by the user.
{
"verified": true,
"backup_codes": [
"a1b2c3d4", "e5f6g7h8", "i9j0k1l2", "m3n4o5p6", "q7r8s9t0",
"u1v2w3x4", "y5z6a7b8", "c9d0e1f2", "g3h4i5j6", "k7l8m9n0"
]
} 3. Login with MFA
When a user with MFA logs in:
POST /v1/acme/auth/login
{ "email": "alice@acme.com", "password": "..." }
# Response (MFA required):
{ "mfa_required": true, "mfa_token": "temp-token" }
# Second request with TOTP code:
POST /v1/acme/auth/login
{ "email": "alice@acme.com", "password": "...", "mfa_code": "123456" }
# Or with backup code:
{ "email": "alice@acme.com", "password": "...", "mfa_code": "a1b2c3d4" } MFA Policy
Configure MFA requirements at the tenant or organization level:
| Policy | Behavior |
|---|---|
optional | Users can choose to enable MFA |
encouraged | Prompt users to enable MFA (but don’t block) |
required | All users must have MFA enabled to log in |
PATCH /manage/v1/acme/tenant
{ "mfa_policy": "required" } MFA in Access Policies
eBPF and AuthFI Connect policies can require MFA:
{
"method": "POST",
"path_pattern": "/api/admin/*",
"required_roles": ["admin"],
"require_mfa": true
} The JWT contains "mfa_verified": true when the user’s session includes a verified MFA challenge.
List Factors
GET /v1/acme/mfa/factors
Authorization: Bearer <access_token> Returns enrolled factors (type, verified status). Secrets are never returned.
Unenroll
POST /v1/acme/mfa/unenroll
Authorization: Bearer <access_token>
{ "factor_id": "factor-uuid", "code": "123456" } Requires a valid TOTP code to confirm unenrollment — prevents unauthorized removal.