[PR #24840] [CLOSED] feat: add optional TOTP two-factor authentication #131551

Closed
opened 2026-05-21 17:11:25 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/open-webui/open-webui/pull/24840
Author: @jeremy-windsor
Created: 5/17/2026
Status: Closed

Base: devHead: feat/totp-2fa


📝 Commits (1)

  • 116192d feat: add optional TOTP two-factor authentication

📊 Changes

14 files changed (+1680 additions, -75 deletions)

View changed files

backend/open_webui/migrations/versions/f6b90f8a2c1d_add_user_totp_table.py (+48 -0)
📝 backend/open_webui/models/auths.py (+2 -0)
backend/open_webui/models/totp.py (+206 -0)
📝 backend/open_webui/routers/auths.py (+326 -9)
📝 backend/open_webui/routers/users.py (+51 -0)
📝 backend/open_webui/utils/oauth.py (+75 -53)
backend/open_webui/utils/totp.py (+122 -0)
📝 src/lib/apis/auths/index.ts (+190 -0)
📝 src/lib/apis/users/index.ts (+54 -0)
📝 src/lib/components/admin/Users/UserList/EditUserModal.svelte (+57 -3)
📝 src/lib/components/chat/Settings/Account.svelte (+8 -1)
src/lib/components/chat/Settings/Account/TOTP.svelte (+335 -0)
📝 src/routes/auth/+page.svelte (+156 -9)
test/test_totp_utils.py (+50 -0)

📄 Description

Pull Request Checklist

Before submitting, make sure you've checked the following:

  • Linked Issue/Discussion: Relates to #1225. Also references #24650, #11953, and #16461.
  • Target branch: This PR targets dev.
  • Description: A concise description of the changes is provided below.
  • Changelog: A changelog entry following Keep a Changelog format is included at the bottom.
  • Documentation: Docs repo update is prepared; see docs draft below.
  • Dependencies: No new dependencies were added.
  • Testing: Manual tests were performed. Screenshots are included where applicable.
  • No Unchecked AI Code: AI-assisted changes have undergone human review and manual testing.
  • Self-Review: A self-review of the code has been performed.
  • Architecture: Smart defaults are used; TOTP is optional per user and disabled by default.
  • Git Hygiene: Atomic feature branch based on upstream/dev; no unrelated commits intended.
  • Title Prefix: feat: add optional TOTP two-factor authentication

Description

Adds optional per-user TOTP two-factor authentication for Open WebUI login.

Relates to #1225.
Refs #24650.
Addresses prior feedback from #11953 and #16461 around optional defaults, migration compatibility, metadata, rate limiting, backup-code behavior, and dependency scope.

This PR intentionally keeps QR-code rendering and admin-wide enforcement out of scope so the first TOTP slice stays small, dependency-free, and reviewable. Setup uses an authenticator-app compatible otpauth:// URI plus a manual setup key.

Manual Testing

  • Verified password login without TOTP remains unchanged.
  • Verified TOTP setup from Account settings.
  • Verified TOTP login challenge after password login.
  • Verified authenticator-code login.
  • Verified backup-code login.
  • Verified used backup codes cannot be reused.
  • Verified backup-code remaining count updates.
  • Verified admin can see and reset a user's TOTP status.
  • Verified OAuth callback/token-exchange paths return a TOTP challenge when local TOTP is enabled.
  • Verified sandbox UI manually.

Automated / Local Checks

  • git diff --check
  • Backend py_compile for touched Python files
  • Direct RFC HOTP/TOTP vector checks
  • Backup-code normalize/hash/verify checks
  • npm run test:frontend
  • ./node_modules/.bin/vite build

Note: npm run build also passed, but the existing pyodide:fetch step pulled a newer black wheel and dirtied static/pyodide/pyodide-lock.json. That generated change was intentionally excluded from this PR.

Screenshots or Videos

MFA login challenge screenshot:

/tmp/open-webui-totp-sandbox/screenshots/totp-login-mfa.png

Recommended additional PR screenshots before marking ready:

  • Account settings before TOTP is enabled.
  • TOTP setup key / authenticator URI state.
  • Backup codes shown immediately after enable/regenerate.
  • Admin user edit modal showing TOTP status/reset.

Changelog Entry

Description

  • Adds optional per-user TOTP two-factor authentication to protect Open WebUI login for self-hosted instances.

Added

  • Per-user TOTP setup and management in Account settings.
  • TOTP challenge support for password, LDAP, trusted-header/no-auth, OAuth callback, and OAuth token-exchange login flows.
  • One-time backup codes for account recovery.
  • Admin TOTP status and reset control for user recovery.
  • TOTP metadata including creation and last-used timestamps.
  • TOTP replay protection using the last-used time step, updated in the same locked transaction as verification.
  • Rate limiting for TOTP verification flows.

Changed

  • Login responses can now return an MFA challenge when TOTP is enabled for the user.

Deprecated

  • None.

Removed

  • None.

Fixed

  • None.

Security

  • TOTP secrets are encrypted with a key derived from WEBUI_SECRET_KEY.
  • Backup codes are hashed with bcrypt.
  • TOTP verification is rate-limited.
  • TOTP and backup-code verification update usage state atomically to avoid double-use races.
  • TOTP is disabled by default and must be explicitly enabled per user.
  • No new dependencies were added.

Breaking Changes

  • None.

Additional Information

  • Changing WEBUI_SECRET_KEY invalidates encrypted TOTP secrets.
  • Multi-instance deployments should use shared rate-limiting state if Open WebUI supports/configures it for the deployment.
  • API keys remain bearer credentials and are not changed by login-time TOTP.
  • QR-code rendering and admin-wide TOTP enforcement are follow-up scope.

Contributor License Agreement

Note

Deleting the CLA section will lead to immediate closure of your PR and it will not be merged in.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/open-webui/open-webui/pull/24840 **Author:** [@jeremy-windsor](https://github.com/jeremy-windsor) **Created:** 5/17/2026 **Status:** ❌ Closed **Base:** `dev` ← **Head:** `feat/totp-2fa` --- ### 📝 Commits (1) - [`116192d`](https://github.com/open-webui/open-webui/commit/116192d98d13010aa5746f63ed772caad8dd1a6c) feat: add optional TOTP two-factor authentication ### 📊 Changes **14 files changed** (+1680 additions, -75 deletions) <details> <summary>View changed files</summary> ➕ `backend/open_webui/migrations/versions/f6b90f8a2c1d_add_user_totp_table.py` (+48 -0) 📝 `backend/open_webui/models/auths.py` (+2 -0) ➕ `backend/open_webui/models/totp.py` (+206 -0) 📝 `backend/open_webui/routers/auths.py` (+326 -9) 📝 `backend/open_webui/routers/users.py` (+51 -0) 📝 `backend/open_webui/utils/oauth.py` (+75 -53) ➕ `backend/open_webui/utils/totp.py` (+122 -0) 📝 `src/lib/apis/auths/index.ts` (+190 -0) 📝 `src/lib/apis/users/index.ts` (+54 -0) 📝 `src/lib/components/admin/Users/UserList/EditUserModal.svelte` (+57 -3) 📝 `src/lib/components/chat/Settings/Account.svelte` (+8 -1) ➕ `src/lib/components/chat/Settings/Account/TOTP.svelte` (+335 -0) 📝 `src/routes/auth/+page.svelte` (+156 -9) ➕ `test/test_totp_utils.py` (+50 -0) </details> ### 📄 Description <!-- Critical Open WebUI PR requirements: - Target branch: dev - Keep the CLA section intact --> # Pull Request Checklist **Before submitting, make sure you've checked the following:** - [x] **Linked Issue/Discussion:** Relates to #1225. Also references #24650, #11953, and #16461. - [x] **Target branch:** This PR targets `dev`. - [x] **Description:** A concise description of the changes is provided below. - [x] **Changelog:** A changelog entry following Keep a Changelog format is included at the bottom. - [ ] **Documentation:** Docs repo update is prepared; see docs draft below. - [x] **Dependencies:** No new dependencies were added. - [x] **Testing:** Manual tests were performed. Screenshots are included where applicable. - [x] **No Unchecked AI Code:** AI-assisted changes have undergone human review and manual testing. - [x] **Self-Review:** A self-review of the code has been performed. - [x] **Architecture:** Smart defaults are used; TOTP is optional per user and disabled by default. - [x] **Git Hygiene:** Atomic feature branch based on `upstream/dev`; no unrelated commits intended. - [x] **Title Prefix:** `feat: add optional TOTP two-factor authentication` ## Description Adds optional per-user TOTP two-factor authentication for Open WebUI login. Relates to #1225. Refs #24650. Addresses prior feedback from #11953 and #16461 around optional defaults, migration compatibility, metadata, rate limiting, backup-code behavior, and dependency scope. This PR intentionally keeps QR-code rendering and admin-wide enforcement out of scope so the first TOTP slice stays small, dependency-free, and reviewable. Setup uses an authenticator-app compatible `otpauth://` URI plus a manual setup key. ## Manual Testing - Verified password login without TOTP remains unchanged. - Verified TOTP setup from Account settings. - Verified TOTP login challenge after password login. - Verified authenticator-code login. - Verified backup-code login. - Verified used backup codes cannot be reused. - Verified backup-code remaining count updates. - Verified admin can see and reset a user's TOTP status. - Verified OAuth callback/token-exchange paths return a TOTP challenge when local TOTP is enabled. - Verified sandbox UI manually. ## Automated / Local Checks - `git diff --check` - Backend `py_compile` for touched Python files - Direct RFC HOTP/TOTP vector checks - Backup-code normalize/hash/verify checks - `npm run test:frontend` - `./node_modules/.bin/vite build` Note: `npm run build` also passed, but the existing `pyodide:fetch` step pulled a newer `black` wheel and dirtied `static/pyodide/pyodide-lock.json`. That generated change was intentionally excluded from this PR. ## Screenshots or Videos MFA login challenge screenshot: `/tmp/open-webui-totp-sandbox/screenshots/totp-login-mfa.png` Recommended additional PR screenshots before marking ready: - Account settings before TOTP is enabled. - TOTP setup key / authenticator URI state. - Backup codes shown immediately after enable/regenerate. - Admin user edit modal showing TOTP status/reset. # Changelog Entry ### Description - Adds optional per-user TOTP two-factor authentication to protect Open WebUI login for self-hosted instances. ### Added - Per-user TOTP setup and management in Account settings. - TOTP challenge support for password, LDAP, trusted-header/no-auth, OAuth callback, and OAuth token-exchange login flows. - One-time backup codes for account recovery. - Admin TOTP status and reset control for user recovery. - TOTP metadata including creation and last-used timestamps. - TOTP replay protection using the last-used time step, updated in the same locked transaction as verification. - Rate limiting for TOTP verification flows. ### Changed - Login responses can now return an MFA challenge when TOTP is enabled for the user. ### Deprecated - None. ### Removed - None. ### Fixed - None. ### Security - TOTP secrets are encrypted with a key derived from `WEBUI_SECRET_KEY`. - Backup codes are hashed with bcrypt. - TOTP verification is rate-limited. - TOTP and backup-code verification update usage state atomically to avoid double-use races. - TOTP is disabled by default and must be explicitly enabled per user. - No new dependencies were added. ### Breaking Changes - None. --- ### Additional Information - Changing `WEBUI_SECRET_KEY` invalidates encrypted TOTP secrets. - Multi-instance deployments should use shared rate-limiting state if Open WebUI supports/configures it for the deployment. - API keys remain bearer credentials and are not changed by login-time TOTP. - QR-code rendering and admin-wide TOTP enforcement are follow-up scope. ### Contributor License Agreement <!-- 🚨 DO NOT DELETE THE TEXT BELOW 🚨 Keep the "Contributor License Agreement" confirmation text intact. Deleting it will trigger the CLA-Bot to INVALIDATE your PR. Your PR will NOT be reviewed or merged until you check the box below confirming that you have read and agree to the terms of the CLA. --> - [x] By submitting this pull request, I confirm that I have read and fully agree to the [Contributor License Agreement (CLA)](https://github.com/open-webui/open-webui/blob/main/CONTRIBUTOR_LICENSE_AGREEMENT), and I am providing my contributions under its terms. > [!NOTE] > Deleting the CLA section will lead to immediate closure of your PR and it will not be merged in. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-05-21 17:11:25 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/open-webui#131551