Two-Factor Authentication
ProxCenter supports TOTP-based two-factor authentication (2FA) for local and LDAP accounts. OIDC accounts rely on the identity provider's own MFA: ProxCenter does not add a second factor on top of an OIDC sign-in.
What is TOTP?
TOTP (Time-based One-Time Password) is the 6-digit code rotating every 30 seconds shown by authenticator apps like Google Authenticator, Authy, 1Password, Bitwarden, or Microsoft Authenticator. ProxCenter follows RFC 6238 with a SHA-1 HMAC and a one-step drift window on either side of the current time to absorb minor clock skew.
Enabling 2FA on your account
- Sign in and navigate to Profile.
- In the Two-Factor Authentication card, click Enable 2FA.
- Scan the QR code with your authenticator app, or copy the secret manually.
- Enter the 6-digit code shown by the app and click Verify.
- Download and store the 10 recovery codes in a safe place. Each code works only once.
- Tick the confirmation checkbox and click Done.
From the next sign-in onward, ProxCenter will ask for the authenticator code after your password.
Signing in with 2FA
After your password is accepted, a dialog asks for the 6-digit code from your authenticator. You can also enter one of your recovery codes in the same field (format XXXXX-XXXXX). A recovery code is consumed and cannot be reused.
If you cancel the dialog the password is dropped from memory; you'll need to re-enter it on the next attempt.
Disabling 2FA
Open Profile, click Disable 2FA in the 2FA card, and confirm with either your password or a current TOTP code. If your administrator has enabled the "Require 2FA for super_admin" policy and you are a super_admin, disabling your own 2FA is refused with a 409 to prevent locking the platform.
Recovery codes
You start with 10 single-use recovery codes. The 2FA card highlights the remaining count and warns once 3 or fewer remain. Click Regenerate recovery codes (requires re-authentication) to invalidate the entire previous batch and issue a fresh set.
Lost device
If you lose access to both your authenticator app and your recovery codes:
- Use any remaining recovery code from your saved backup.
- Otherwise ask a
super_adminto reset your 2FA from Security > Users: click the disable-2FA action on your row and confirm by typing your email. - As a last resort a
super_admincan clear the relevant columns directly on the database (totp_enabled,totp_secret_enc,totp_enrolled_at,totp_last_used_steponusers, plusDELETE FROM user_totp_recovery_codes WHERE user_id = '…'). Document this step in your operations runbook.
Administrator policy: require 2FA for super_admin
A super_admin can enforce 2FA on all super_admin accounts via Security > Compliance > Policies > Two-Factor Authentication Policy > Require 2FA for super_admin accounts.
Enabling the policy is gated: ProxCenter refuses the toggle (HTTP 409) if the admin attempting to enable it does not yet have 2FA on their own account. This is intentional and prevents an administrator from locking themselves out by mistake.
Once enabled:
- A super_admin without 2FA can still sign in, but every protected page navigation and every protected API call redirects them to
/profile/2fa/enrollmentuntil they complete the wizard. - The forced enrollment screen has no cancel affordance. The user must finish the flow before regaining the rest of the application.
- After enrollment, the session JWT is re-minted server-side so the next request bypasses the redirect without requiring a full sign-out and sign-in.
OIDC accounts
ProxCenter does not add a second factor on top of OIDC sign-ins. Configure MFA in your identity provider (Entra ID Conditional Access, Okta MFA, Authentik flows, Duo, Keycloak, etc.). The IdP's MFA takes effect on the OIDC sign-in step before the ProxCenter session is even created.
The 2FA card on Profile is hidden for OIDC users and replaced by a notice pointing back to the identity provider.
Replay defense
ProxCenter records the latest TOTP step number consumed by each user and refuses to accept a code that maps to the same or an earlier step. This means a 6-digit code is single-use even within its 30-second window, defeating an attacker who would otherwise capture and replay a still-valid code on a parallel request.
Audit trail
The following events are written to the audit log under category auth:
| Action | Status | Notes |
|---|---|---|
2fa_enrolled | success | After the wizard completes |
2fa_disabled | success | details.by = "self" or "admin" |
2fa_login_failed | failure | details.reason = "invalid_code" | "invalid_recovery" | "malformed" |
2fa_recovery_used | success | details.remaining = N |
2fa_recovery_low | warning | Emitted when remaining count drops below 3 |
2fa_recovery_regenerated | success | After the regenerate flow |
Successful 2FA logins are reported on the existing login event via the factors payload (currently logged only at backend level, not surfaced in the audit UI yet).