Requiring two-factor
Make two-factor authentication mandatory for an organization's members, limit it to authenticator apps, and decide how long a device may be remembered.
Each user decides whether to turn on two-factor authentication for their own account. An organization can also require it: every member must have a factor before they can do anything in that organization. The requirement belongs to the organization, so a person in three organizations meets the strictest one only while acting in it.
What a member experiences
A member who already has a factor notices nothing. A member who has none is not locked out, because setting up a factor needs a session. Instead:
They get a restricted session
Signing in (or switching into the organization) succeeds, and the response carries
mfaEnrollmentRequired: true with the organization asking:
{
"mfaEnrollmentRequired": true,
"mfaEnrollment": {
"orgUid": "0199a5f0-9e33-7d42-b6a8-2f1c0e7d5b19",
"orgName": "Northwind Clinics",
"allowedKinds": ["totp"]
},
"auth": { "accessToken": "eyJhbGciOi...", "refreshToken": "eyJhbGciOi...", "activeOrgUid": "0199a5f0-9e33-7d42-b6a8-2f1c0e7d5b19" }
}The session works only for getting out of that state
It can enroll and manage factors, read the organization's requirement, refresh, sign out, list
the user's organizations and switch to another one. Anything else answers
403 MFA_ENROLLMENT_REQUIRED.
Once a factor is confirmed, refresh
The next refresh issues an ordinary session.
Never sign the user out on MFA_ENROLLMENT_REQUIRED
Route them to your enrollment screen instead. Signing them out only brings them back to the same state on their next sign-in. The other way out is switching to an organization that does not require 2FA, which is why the organization list stays reachable.
The requirement is checked on every sign-in and every refresh, including the refresh that switches organization. Turning it on therefore reaches every existing session within one access token lifetime (15 minutes), without signing anyone out, and switching organization can never step around it.
Setting the requirement
An organization's owner and administrators set it for their active organization. Any member can read it, so a member being asked to enroll can see which organization is asking and what counts.
# Read
curl "$AUTHORIC_URL/$APP_UID/auth/org-security" \
-H "Authorization: Bearer $ACCESS_TOKEN"
# Require 2FA, authenticator apps only, remember devices for 14 days
curl -X POST "$AUTHORIC_URL/$APP_UID/auth/org-security" \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "mfaRequired": true, "allowedKinds": ["totp"], "rememberDeviceDays": 14 }'{
"orgUid": "0199a5f0-9e33-7d42-b6a8-2f1c0e7d5b19",
"orgName": "Northwind Clinics",
"mfaRequired": true,
"allowedKinds": ["totp"],
"callerSatisfies": true,
"rememberDeviceDays": 14,
"rememberDeviceDefaultDays": 30,
"rememberDeviceMaxDays": 90
}| Field | Meaning |
|---|---|
mfaRequired | Required. true requires a factor of every member; false clears the requirement. |
allowedKinds | Which factors count: ["totp"] for authenticator apps only (the usual answer to SIM-swap risk), or ["totp", "sms"]. Omit or send null for any kind. An empty list is refused rather than read as "any". |
rememberDeviceDays | How long a device may skip the challenge, 0 to 90. 0 forbids remembering devices and forgets the ones already remembered for this organization. Omit it to leave it unchanged; null (never set) means the 30-day default. |
callerSatisfies | On a read: whether the caller already has a factor that counts, so your UI can explain a disabled switch before anyone clicks it. |
Turning it on is guarded; turning it off is not
Requiring 2FA is refused for a caller who has no qualifying factor of their own
(409 ORG_MFA_ENABLE_BLOCKED): otherwise the first person to use the setting would be the first
person it locks out. Clearing it is always allowed, so an organization that has boxed itself in can
be rescued by whoever can still get in.
A member's factor counts if it is confirmed, whether or not it can be reached right now. A phone factor still satisfies the requirement when your plan's SMS allowance has run out; the user is offered their other factors or recovery codes at sign-in instead.
Your own Authoric organization
The same switches exist for the organization you sign in to the console with, under Settings › General, with the same rules: the requirement applies on every refresh, a member without a factor is held on a setup screen rather than signed out, and you cannot turn it on until you have a factor yourself.
Errors to branch on
| Code | Status | Meaning |
|---|---|---|
MFA_ENROLLMENT_REQUIRED | 403 | This session owes a factor for its organization. Send the user to enroll. |
ORG_MFA_ENABLE_BLOCKED | 409 | Set up your own factor before requiring one. |
MFA_LAST_FACTOR | 409 | Pausing this factor would leave nothing that satisfies the organization. |