Two-factor authentication (2FA)
Add a second factor — authenticator app or passkey — to your sign-in.
Overview
2FA significantly reduces account takeover risk. The platform supports TOTP authenticator apps (Google Authenticator, Authy, 1Password) and passkeys (passkey). Owners can enforce 2FA for all clinic users.
Prerequisites
- Active sign-in
- Smartphone with an authenticator app, or a device that supports passkeys (Touch ID, Face ID, Windows Hello, security key)
Steps
Open Security settings. Avatar → My Profile → Security, or Settings → Security.
Click "Set up authenticator app". A QR code displays with a manual-entry secret beside it.
Open your authenticator app. Tap + → Scan QR code. Scan the code on screen.
Confirm enrolment. The app shows a 6-digit rotating code. Type it into the platform's verification field.
Save backup codes. A list of 10 one-time-use codes appears. Save these in a secure place (password manager, encrypted note). Each can be used once if you lose your phone.
Sign out and sign in to test. Sign out, sign in. After password, the platform asks for the 6-digit code. Enter it.
Optionally add a passkey too. Set up passkey uses passkey — see Passkeys.
Owner: enforce 2FA for everyone. Owner only. Settings → Security → 2FA enforcement: Required. After change, every user must enable 2FA on their next sign-in.
Expected outcome
- Your account requires 2FA on every sign-in
- Backup codes available if you lose phone
- Owner can enforce 2FA across the clinic
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| QR code won't scan | Camera issues | Use the manual-entry secret instead |
| 6-digit code rejected | Time skew on phone | Sync your phone's clock |
| Lost phone, no backup codes | Account effectively locked | Owner/Admin can disable 2FA on your user from Settings → Staff |
| Want to disable 2FA | Reduces security; possible if not enforced | Settings → Security → Disable 2FA → re-enter password |
| Owner enforced but staff can't enable | Network blip during setup | Re-try; the QR is regenerated each time |