mirror of
https://github.com/open-webui/open-webui.git
synced 2026-07-16 14:39:31 -05:00
[PR #24626] feat: optional HS256 JWT for forwarded user identity headers #115057
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/open-webui/open-webui/pull/24626
Author: @jmleksan
Created: 5/12/2026
Status: 🔄 Open
Base:
dev← Head:feat/user-jwt-header📝 Commits (1)
9d07481feat: add JWT support for user info headers📊 Changes
2 files changed (+51 additions, -3 deletions)
View changed files
📝
backend/open_webui/env.py(+10 -0)📝
backend/open_webui/utils/headers.py(+41 -3)📄 Description
Before submitting, make sure you've checked the following:
dev(notmain).PyJWT(import jwt) already used elsewhere in the backend.ENABLE_FORWARD_USER_INFO_HEADERS=trueandFORWARD_USER_JWT_SECRETset, outbound requests includeFORWARD_USER_JWT_HEADER(defaultX-OpenWebUI-User-Jwt) with HS256 JWT; claimssub,email,name,role,iss(open-webui),iat,exp. Without secret, legacyX-OpenWebUI-User-*headers unchanged. Gateway decode with shared secret succeeds.env.pyint-parse patterns and centralizes behavior ininclude_user_info_headersso all existing call sites pick it up.FORWARD_USER_JWT_SECRETis unset.Changelog Entry
"ENABLE_FORWARD_USER_INFO_HEADERS"is enabled, setting"FORWARD_USER_JWT_SECRET"sends a short-lived HS256 JWT in"FORWARD_USER_JWT_HEADER"instead of the separate"X-OpenWebUI-User-*"headers, so OpenAI-compatible gateways and tool backends can verify user context with a shared secret.Description
When
ENABLE_FORWARD_USER_INFO_HEADERSis enabled, operators can optionally setFORWARD_USER_JWT_SECRETso Open WebUI sends one HS256 JWT (header name configurable) carryingsub,email,name, androleinstead of the four separateX-OpenWebUI-User-*headers. This lets upstream gateways verify user context cryptographically with a shared secret instead of trusting plain header strings alone which should prevent spoofing of headers by bad actors. If minting fails, behavior falls back to the legacy headers.Added
FORWARD_USER_JWT_SECRET,FORWARD_USER_JWT_HEADER(defaultX-OpenWebUI-User-Jwt),FORWARD_USER_JWT_EXPIRES_SECONDS(default300, invalid values fall back to300).sub(user id),email,name,role,iss(open-webui),iat,exp(HS256).Changed
include_user_info_headers: whenFORWARD_USER_JWT_SECRETis non-empty, adds only the configured JWT header and omits the four legacy user info headers for that request path.Security
issis fixed toopen-webuifor verification pinning.Breaking Changes
FORWARD_USER_JWT_SECRETis set, upstreams that previously relied only onX-OpenWebUI-User-Name/Id/Email/Rolewill no longer receive those four headers from this path; they must accept the JWT header instead. UnsetFORWARD_USER_JWT_SECRETto restore legacy behavior.Additional Information
backend/open_webui/env.py(env wiring),backend/open_webui/utils/headers.py(_mint_forward_user_jwt+ branch ininclude_user_info_headers).WEBUI_SECRET_KEY) is unchanged; this is a separate optional secret for gateway-facing assertions.include_user_info_headers.Screenshots or Videos
Contributor License Agreement
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.