Two-factor authentication
Native TOTP 2FA, workspace enforcement policy, and admin recovery for locked-out users.
orboto has native time-based one-time-password (TOTP) two-factor authentication. A user pairs an authenticator app (Google Authenticator, 1Password, Aegis, etc.), and from then on a 6-digit code is required as a second step after the password at sign-in.
This is a Business/Enterprise feature. On the Community plan it works but raises a soft-warn on the License page; nothing is blocked.
It is standard RFC 6238 TOTP: HMAC-SHA1, 30-second step, 6 digits, with a ±1 step tolerance for clock drift. Any compliant authenticator app works - there is no orboto-specific app to install.

For users
Enrol
- Go to Profile → Two-factor authentication and click Enable 2FA.
- Scan the QR code with your authenticator app, or type the shown secret key in manually.
- Enter the current 6-digit code to confirm. 2FA is now on.
- Save your backup codes. Ten one-time codes are shown once, right after you confirm. Copy or download them and store them somewhere safe (a password manager). Each code works exactly once.


Sign in with 2FA on
After your email + password are accepted, orboto asks for your authentication code. Open your authenticator app and enter the current 6-digit code. If you don't have your device, enter one of your backup codes in the same field instead.
Too many wrong codes in a row temporarily locks the code step for a few minutes (brute-force protection). Wait, then try again with a fresh code.
Disable
Profile → Two-factor authentication → Disable 2FA, then enter a current code or a backup code. This removes your secret and all remaining backup codes.
Lost your device and your backup codes
Ask a workspace admin to reset your 2FA (see below). After a reset you sign in with your password only, and should immediately enrol again - especially if the workspace requires 2FA.
For admins
Reset a user's 2FA
Admin → Users → the user's row → Reset 2FA. This clears the user's TOTP secret and backup codes; you can optionally add a reason, which is shown to the affected user. It's reversible in the sense that the user can simply enrol again - it does not expose any secret.
Resetting someone else's 2FA is a takeover-adjacent action: it requires
admin:users:write, and you must have completed your own MFA
challenge recently (a step-up check) before the reset goes through. If
the user had 2FA enabled, they're notified in-app and by email that an
admin disabled it.

Require 2FA for the workspace
Admin → Security has an MFA enforcement card with three modes:
- Off - nobody is required to have 2FA.
- All - every local (password) account must enrol.
- Roles - only accounts holding the listed global roles must enrol
(for example
super-admin, admin).
Two more settings apply whenever a mode other than Off is active:
- Exempt SSO accounts (on by default) - see below.
- Grace days - how many days a newly-covered account gets to enrol
before being blocked.
0means immediate enforcement.
A blocked account can only reach the 2FA setup flow, sign-out, and its own profile until it enrols. The same card shows a compliance table: every active user, their global roles, and whether 2FA is currently on - useful for confirming a rollout actually landed before you tighten the grace period.

Reading the policy requires admin:system:read; changing it requires
admin:system:write.
SSO and 2FA
The enforcement policy applies to local password accounts. Users who sign in through SSO (OIDC / SAML) are, by default, not asked for an orboto TOTP code and not subject to the policy - their second factor is enforced by your identity provider, which is where it belongs. Uncheck Exempt SSO accounts in the enforcement policy if you want SSO users covered too. Configure MFA on the IdP side via SSO setup.
A user who has both a password and an SSO identity, signing in with the password on a domain that isn't SSO-enforced, is treated as a local account and is subject to the policy.
How it works (operator notes)
- The TOTP secret is stored AES-256-GCM-encrypted, keyed from
MFA_ENC_SECRET(falling back toJWT_SECRETif unset). Set a dedicatedMFA_ENC_SECRETin production and rotate it like any other secret - rotating it invalidates existing enrolments, and users re-enrol. - Backup codes are stored only as SHA-256 hashes; the plaintext is shown once at generation and never again. A backup code is single-use.
- Login is two-step: a correct password for a 2FA-enabled user yields a short-lived (5-minute) challenge token, not a session. The session is issued only after a valid TOTP or backup code is presented. The code step is rate-limited per account and additionally capped per IP.
- Backup-code count is fixed at ten and regenerated (replacing any prior set) every time 2FA is confirmed.
Audit events
| Action | When |
|---|---|
mfa.enabled | a user confirms enrolment |
mfa.disabled | a user disables their own 2FA |
mfa.admin_reset | an admin resets a user's 2FA |
auth.mfa_challenge_success | a login challenge is passed |
auth.mfa_challenge_failed | a wrong code at the login challenge (includes whether it tripped the lock) |
Troubleshooting
Reset 2FA action is greyed out or fails. You need a recent MFA
challenge of your own - sign out and back in (completing your own 2FA
step) before retrying, in addition to holding admin:users:write.
A user is locked out even though "Exempt SSO accounts" is on. That exemption only applies to accounts actually bound to an SSO provider. Someone with both a password and an SSO identity, signing in with the password, is treated as local and stays covered by the policy.
Rolled out enforcement but some accounts still show 2FA off. Check the grace days setting - accounts inside their grace window are allowed to sign in without 2FA yet. The compliance table on the enforcement card shows exactly who's still unenrolled.