[GH-ISSUE #22863] feat: Add OAUTH_AUTHORIZE_PARAMS env var for extra OIDC authorization redirect parameters #35359

Closed
opened 2026-04-25 09:34:48 -05:00 by GiteaMirror · 2 comments
Owner

Originally created by @rndmcnlly on GitHub (Mar 19, 2026).
Original GitHub issue: https://github.com/open-webui/open-webui/issues/22863

Problem Description

When Open WebUI is configured to use an OIDC broker — a provider that itself presents
a picker UI for choosing among multiple upstream identity providers — the
GET /oauth/oidc/login redirect lands users on the broker's full picker page with no
guidance. In deployments where only one upstream IdP is valid, this creates two
problems:

  1. User confusion. The picker is unfamiliar and lists hundreds or thousands of
    options (e.g. CILogon lists ~5,000 academic institutions). Users don't know what to
    pick.

  2. Silent wrong-IdP failure. A user who picks "Google" or another social IdP
    authenticates successfully at the broker, then hits OWUI's OAUTH_ALLOWED_DOMAINS
    gate and receives a generic "Invalid credentials" error — with no indication that
    they chose the wrong IdP. They completed what looked like a successful login.

Every major OIDC broker provides a query parameter on the authorization endpoint to
pre-select or restrict the upstream IdP:

Broker Parameter
CILogon (InCommon / research federations) idphint=<entityID>
Keycloak kc_idp_hint=<alias>
Dex connector_id=<id>

There is currently no way to inject these parameters through Open WebUI configuration.


Desired Solution

Add a single new environment variable OAUTH_AUTHORIZE_PARAMS that accepts a JSON
object. Its key/value pairs are merged into the **kwargs passed to authlib's
client.authorize_redirect() in handle_login(), appending them as query parameters
on the authorization redirect URL.

backend/open_webui/config.py — add alongside OAUTH_AUDIENCE:

OAUTH_AUTHORIZE_PARAMS = PersistentConfig(
    "OAUTH_AUTHORIZE_PARAMS",
    "oauth.oidc.authorize_params",
    os.environ.get("OAUTH_AUTHORIZE_PARAMS", ""),
)

backend/open_webui/utils/oauth.py — in handle_login():

kwargs = {}
if auth_manager_config.OAUTH_AUDIENCE:
    kwargs["audience"] = auth_manager_config.OAUTH_AUDIENCE
if auth_manager_config.OAUTH_AUTHORIZE_PARAMS:
    try:
        extra = json.loads(auth_manager_config.OAUTH_AUTHORIZE_PARAMS)
        if isinstance(extra, dict):
            kwargs.update(extra)
    except (json.JSONDecodeError, TypeError):
        log.warning("OAUTH_AUTHORIZE_PARAMS is not valid JSON, ignoring")

return await client.authorize_redirect(request, redirect_uri, **kwargs)

Why this is trivially small: authlib's authorize_redirect already accepts and
passes **kwargs verbatim through create_authorization_urlprepare_grant_uri
→ URL query string. The library already does the right thing — OWUI just needs to
surface a way to populate those kwargs from config. This was confirmed by reading the
authlib v1.6.6 source. OAUTH_AUDIENCE (added in #19768) is the direct precedent,
already using this exact mechanism for a single hardcoded key.

Example usage:

# CILogon — show only UC Santa Cruz in the IdP picker
OAUTH_AUTHORIZE_PARAMS={"idphint": "urn:mace:incommon:ucsc.edu"}

# Keycloak — bypass broker picker, go directly to a configured upstream IdP
OAUTH_AUTHORIZE_PARAMS={"kc_idp_hint": "google"}

# Any provider — require MFA even when a session already exists
OAUTH_AUTHORIZE_PARAMS={"acr_values": "https://refeds.org/profile/mfa"}

Alternatives Considered

  • One env var per known param (OAUTH_IDP_HINT, OAUTH_LOGIN_HINT, etc.):
    Rejected — different brokers use different parameter names. A generic dict avoids
    combinatorial growth and handles parameters we haven't anticipated.

  • OAUTH_ALLOWED_DOMAINS as the sole guard: Already works, but only as a
    post-authentication reject. The user experience of completing a login only to
    receive "Invalid credentials" is poor. The goal is to prevent the wrong path
    from being reachable at all.

  • Operator patches / custom fork: Defeats the purpose of a configurable
    deployment.


Additional Context

  • Authlib call chain (verified in v1.6.6 source):
    authorize_redirect(**kwargs)create_authorization_url(**kwargs)
    prepare_grant_uri(**kwargs) — kwargs become URL query params verbatim.
  • Direct precedent in this codebase: OAUTH_AUDIENCE / PR #19768, same pattern.
  • Affects only the generic oidc provider path (OAUTH_CLIENT_ID +
    OPENID_PROVIDER_URL). Google, Microsoft, GitHub, and Feishu providers are
    unaffected.
  • No frontend changes required — all OAuth config in OWUI is env-var only.
  • No new dependencies.

Disclosure: issue researched and drafted using the Lathe coding agent toolkit inside of Open WebUI.

Originally created by @rndmcnlly on GitHub (Mar 19, 2026). Original GitHub issue: https://github.com/open-webui/open-webui/issues/22863 ## Problem Description When Open WebUI is configured to use an OIDC broker — a provider that itself presents a picker UI for choosing among multiple upstream identity providers — the `GET /oauth/oidc/login` redirect lands users on the broker's full picker page with no guidance. In deployments where only *one* upstream IdP is valid, this creates two problems: 1. **User confusion.** The picker is unfamiliar and lists hundreds or thousands of options (e.g. CILogon lists ~5,000 academic institutions). Users don't know what to pick. 2. **Silent wrong-IdP failure.** A user who picks "Google" or another social IdP authenticates *successfully* at the broker, then hits OWUI's `OAUTH_ALLOWED_DOMAINS` gate and receives a generic "Invalid credentials" error — with no indication that they chose the wrong IdP. They completed what looked like a successful login. Every major OIDC broker provides a query parameter on the authorization endpoint to pre-select or restrict the upstream IdP: | Broker | Parameter | |---|---| | CILogon (InCommon / research federations) | `idphint=<entityID>` | | Keycloak | `kc_idp_hint=<alias>` | | Dex | `connector_id=<id>` | There is currently no way to inject these parameters through Open WebUI configuration. --- ## Desired Solution Add a single new environment variable `OAUTH_AUTHORIZE_PARAMS` that accepts a JSON object. Its key/value pairs are merged into the `**kwargs` passed to authlib's `client.authorize_redirect()` in `handle_login()`, appending them as query parameters on the authorization redirect URL. **`backend/open_webui/config.py`** — add alongside `OAUTH_AUDIENCE`: ```python OAUTH_AUTHORIZE_PARAMS = PersistentConfig( "OAUTH_AUTHORIZE_PARAMS", "oauth.oidc.authorize_params", os.environ.get("OAUTH_AUTHORIZE_PARAMS", ""), ) ``` **`backend/open_webui/utils/oauth.py`** — in `handle_login()`: ```python kwargs = {} if auth_manager_config.OAUTH_AUDIENCE: kwargs["audience"] = auth_manager_config.OAUTH_AUDIENCE if auth_manager_config.OAUTH_AUTHORIZE_PARAMS: try: extra = json.loads(auth_manager_config.OAUTH_AUTHORIZE_PARAMS) if isinstance(extra, dict): kwargs.update(extra) except (json.JSONDecodeError, TypeError): log.warning("OAUTH_AUTHORIZE_PARAMS is not valid JSON, ignoring") return await client.authorize_redirect(request, redirect_uri, **kwargs) ``` **Why this is trivially small:** authlib's `authorize_redirect` already accepts and passes `**kwargs` verbatim through `create_authorization_url` → `prepare_grant_uri` → URL query string. The library already does the right thing — OWUI just needs to surface a way to populate those kwargs from config. This was confirmed by reading the authlib v1.6.6 source. `OAUTH_AUDIENCE` (added in #19768) is the direct precedent, already using this exact mechanism for a single hardcoded key. **Example usage:** ```env # CILogon — show only UC Santa Cruz in the IdP picker OAUTH_AUTHORIZE_PARAMS={"idphint": "urn:mace:incommon:ucsc.edu"} # Keycloak — bypass broker picker, go directly to a configured upstream IdP OAUTH_AUTHORIZE_PARAMS={"kc_idp_hint": "google"} # Any provider — require MFA even when a session already exists OAUTH_AUTHORIZE_PARAMS={"acr_values": "https://refeds.org/profile/mfa"} ``` --- ## Alternatives Considered - **One env var per known param** (`OAUTH_IDP_HINT`, `OAUTH_LOGIN_HINT`, etc.): Rejected — different brokers use different parameter names. A generic dict avoids combinatorial growth and handles parameters we haven't anticipated. - **`OAUTH_ALLOWED_DOMAINS` as the sole guard:** Already works, but only as a *post-authentication* reject. The user experience of completing a login only to receive "Invalid credentials" is poor. The goal is to prevent the wrong path from being reachable at all. - **Operator patches / custom fork:** Defeats the purpose of a configurable deployment. --- ## Additional Context - Authlib call chain (verified in v1.6.6 source): `authorize_redirect(**kwargs)` → `create_authorization_url(**kwargs)` → `prepare_grant_uri(**kwargs)` — kwargs become URL query params verbatim. - Direct precedent in this codebase: `OAUTH_AUDIENCE` / PR #19768, same pattern. - Affects only the generic `oidc` provider path (`OAUTH_CLIENT_ID` + `OPENID_PROVIDER_URL`). Google, Microsoft, GitHub, and Feishu providers are unaffected. - No frontend changes required — all OAuth config in OWUI is env-var only. - No new dependencies. --- ✨ Disclosure: issue researched and drafted using the [Lathe](https://lathe.tools/) coding agent toolkit inside of Open WebUI.
Author
Owner

@tjbck commented on GitHub (Mar 24, 2026):

Addressed in dev!

<!-- gh-comment-id:4116966852 --> @tjbck commented on GitHub (Mar 24, 2026): Addressed in dev!
Author
Owner

@Classic298 commented on GitHub (Mar 24, 2026):

69171a4c8b

<!-- gh-comment-id:4117009430 --> @Classic298 commented on GitHub (Mar 24, 2026): https://github.com/open-webui/open-webui/commit/69171a4c8bb7f995461b4a2feef194f112b32004
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/open-webui#35359