All posts
Integrator7 min read

Odoo Two-Factor Authentication: TOTP Setup, Enforcement, and Recovery

Two-factor authentication in Odoo uses TOTP (authenticator apps) and can be enforced by user group. This guide covers setup, group-level enforcement, backup codes, and administrator recovery flows.

Odoo 16 and later ships with native TOTP-based two-factor authentication. Users scan a QR code in an authenticator app and enter a 6-digit code at each login. Administrators can enforce 2FA for specific user groups without additional modules.

Enabling 2FA in Settings#

Settings → General Settings → Permissions → Two-Factor Authentication

Three policy options:

  • Optional - users may enable 2FA voluntarily
  • Required for administrators - users in base.group_system must enable 2FA
  • Required for all users - every internal user must enroll; they are redirected to the enrollment wizard on next login

Portal users are never forced into 2FA regardless of the policy.

User Enrollment Flow#

When a user first logs in under a "required" policy without 2FA enabled:

  1. They see the 2FA enrollment page instead of the dashboard
  2. A QR code and manual entry key are displayed
  3. The user scans with their authenticator app and enters the current code to confirm
  4. Odoo stores the TOTP secret (encrypted) on the res.users record

Subsequent logins present the password prompt first, then a second screen for the 6-digit code. The session is not established until both steps succeed.

Backup Codes#

After TOTP enrollment, users generate backup codes under My Profile → Account Security → Generate Backup Codes. Each code is single-use. Odoo generates 8 codes stored as hashed values in res.users_authenticator. They are separate from the TOTP secret.

Administrator Recovery (Lost Device)#

If a user loses their authenticator and has no backup codes, an administrator can reset:

  1. Settings → Users & Companies → Users → open the user
  2. Click Reset Two-Factor Authentication (Security tab)
  3. Confirm the dialog

This deletes the TOTP secret and remaining backup codes. The user must re-enroll on next login.

Programmatic Enforcement per Group#

xml
<record id="base.group_sale_manager" model="res.groups">
  <field name="totp_required">1</field>
</record>

When totp_required is True on any group a user belongs to, that user is subject to 2FA enforcement even if the global policy is "Optional". Group-level enforcement is additive.

Checking Enrollment Status#

python
users_without_2fa = env['res.users'].search([
    ('share', '=', False),
    ('totp_secret', '=', False),
])

Common Mistakes#

  • Enforcing 2FA before users are warned - users mid-session are logged out on next request; send a communication before enabling "Required for all users"
  • Shared accounts with TOTP - TOTP enrollment ties the secret to one device; use separate user accounts with POS-specific groups rather than sharing an account
  • Portal user 2FA confusion - portal users cannot be required to use TOTP; implement MFA at the identity provider layer (e.g., via SAML SSO) for portal access
  • Clock drift on OTP device - TOTP codes are time-based; ensure NTP is running on the Odoo host so the server clock stays accurate

Try ERPeek on your own Odoo module - ask questions, scaffold tests, and explore your codebase in plain language.

Get started free