open-webui / open-webui/open-webui
issue: OAuth role management fails open — skipped entirely when OAUTH_ADMIN_ROLES is empty, and users with no roles claim bypass the 403
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 153k
- Forks
- 22.3k
- Avg merge
- 1d 4h
- Merged PRs (30d)
- 194
Description
Bug Summary
With ENABLE_OAUTH_ROLE_MANAGEMENT=true, role enforcement is silently skipped in two situations, letting users in with DEFAULT_USER_ROLE instead of being denied:
1. Empty OAUTH_ADMIN_ROLES disables ALL role enforcement
In backend/open_webui/utils/oauth.py, get_user_role() (v0.11.1, line ~1532):
if oauth_claim and oauth_allowed_roles and oauth_admin_roles:
If OAUTH_ADMIN_ROLES is empty/unset, the roles claim is never extracted from the token, so the enforcement block below never runs — every user (including ones whose token roles would not match OAUTH_ALLOWED_ROLES) receives DEFAULT_USER_ROLE. There is no warning logged.
Expected: allowed-roles gating should work when only OAUTH_ROLES_CLAIM + OAUTH_ALLOWED_ROLES are configured, or at minimum a startup/login warning that role management is inert.
2. Token with NO roles claim bypasses the 403
Same function (line ~1561):
if oauth_roles:
...
if not matched:
raise HTTPException(status.HTTP_403_FORBIDDEN, ...)
A user whose token carries no roles claim at all gets oauth_roles == [], skips the whole block, and receives DEFAULT_USER_ROLE. This is easy to hit in practice: Keycloak's User Client Role protocol mapper omits the claim entirely when the user has zero roles for the client — i.e. exactly the users who should be denied are the ones who bypass the check. Users with a non-matching claim are correctly denied with 403, so the gate behaves inconsistently depending on claim presence.
Expected: with role management enabled, "no roles" should be treated the same as "no matching roles" → 403 (or at least a configurable strict mode + warning log).
Steps to Reproduce
- Keycloak OIDC provider; client-role based gating: User Client Role mapper → claim
app_roles ENABLE_OAUTH_ROLE_MANAGEMENT=true,OAUTH_ROLES_CLAIM=app_roles,OAUTH_ALLOWED_ROLES=some-group,DEFAULT_USER_ROLE=user- Case 1: leave
OAUTH_ADMIN_ROLESunset → log in with ANY user → activeuseraccount (no role check at all; debug log never prints "User roles from oauth") - Case 2: set
OAUTH_ADMIN_ROLES=some-admin-group→ log in with a user who has no client roles → token has noapp_rolesclaim → debug log showsUser roles from oauth []→ user still getsDEFAULT_USER_ROLEinstead of 403
Environment
- Open WebUI v0.11.1 (logic verified identical on current
main) - OIDC provider: Keycloak 26 (LDAP-federated), client-role mapping via User Client Role protocol mapper
Workaround we ended up with
Deny at the IdP instead: Keycloak per-client authentication-flow override (Conditional sub-flow: Condition - user role negated on an umbrella client role → Deny access), so unauthorized users never reach Open WebUI. Works, but the app-side gate should not fail open.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in backend/open_webui/utils/oauth.py at get_user_role() around the role-claim and enforcement conditions described in the issue. Reproduce both configurations and verify that allowed-role checks still run without OAUTH_ADMIN_ROLES, while tokens with no roles claim are denied with HTTP 403 rather than receiving DEFAULT_USER_ROLE.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- authentication, authorization, backend, security
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 74/100