[PR #22652] [CLOSED] fix: add configurable access_type and prompt for Google OAuth refresh… #26798

Closed
opened 2026-04-20 06:43:05 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/open-webui/open-webui/pull/22652
Author: @ethan-l-geotab
Created: 3/13/2026
Status: Closed

Base: devHead: fix/google-oauth-refresh-token-dev


📝 Commits (1)

  • 7bc28c6 fix: add configurable access_type and prompt for Google OAuth refresh tokens

📊 Changes

1 file changed (+20 additions, -0 deletions)

View changed files

📝 backend/open_webui/config.py (+20 -0)

📄 Description

Pull Request Checklist

  • Target branch: Verify that the pull request targets the dev branch.
  • Description: Provided below.
  • Changelog: Included below.
  • Documentation: Environment variables to be documented in Open WebUI Docs.
  • Dependencies: No new dependencies.
  • Testing: Manually tested on a live deployment — verified refresh token is stored, auto-refresh works after 1 hour, and no behavior change when env vars are unset.
  • Agentic AI Code: AI-assisted but fully human-reviewed and manually tested on a live Kubernetes deployment.
  • Code review: Self-reviewed. Follows the same pattern as existing GOOGLE_OAUTH_SCOPE and OAUTH_TIMEOUT configurations.
  • Design & Architecture: No new settings in the admin UI — env vars only, consistent with existing OAuth config pattern.
  • Git Hygiene: Single atomic commit, rebased on dev.

Changelog Entry

Description

Without access_type=offline in the Google OAuth authorization request, Google only returns a short-lived access token (1 hour) with no refresh_token. The existing refresh logic in OAuthManager._perform_token_refresh() always bails at the if not token_data.get("refresh_token") check because no refresh token is ever stored. After ~55 minutes, the OAuth session is silently deleted from the database, breaking any functionality relying on __oauth_token__ (tools, MCP servers with system_oauth auth) while the user's Open WebUI session remains active.

This is a Google-specific issue: Google requires access_type=offline (a proprietary parameter not part of the OIDC spec) to issue refresh tokens. The OIDC discovery document gives no hint about this parameter, so authlib cannot add it automatically.

This PR adds two new environment variables that populate authorize_params in the Google OAuth client registration, enabling operators to opt in to refresh token support.

Added

  • GOOGLE_OAUTH_ACCESS_TYPE environment variable (default: "") — set to "offline" to request refresh tokens from Google
  • GOOGLE_OAUTH_PROMPT environment variable (default: "") — set to "consent" to force re-consent and guarantee a fresh refresh token for users who previously authorized the app

Changed

  • google_oauth_register() in config.py now conditionally includes authorize_params when either env var is set (empty values are filtered out)

Deprecated

  • N/A

Removed

  • N/A

Fixed

  • Google OAuth sessions no longer expire and get deleted after 1 hour when GOOGLE_OAUTH_ACCESS_TYPE=offline is configured
  • The existing token refresh logic (OAuthManager._perform_token_refresh()) now functions as intended for Google OAuth

Security

  • Refresh tokens are stored encrypted (Fernet) in the existing oauth_session table, consistent with how all other OAuth tokens are stored
  • No change to default behavior — both env vars default to empty, preserving existing behavior for all deployments

Breaking Changes

  • None. Both env vars default to empty, so no behavior change for existing deployments.

Additional Information

  • Why not default to offline? To avoid changing behavior for existing deployments. Operators can opt in by setting GOOGLE_OAUTH_ACCESS_TYPE=offline.
  • Why is prompt separate? Google only returns a refresh token on the first authorization. For users who previously authorized the app, prompt=consent forces re-consent. This can be set temporarily and removed once all users have re-authenticated.
  • Usage example (Helm/K8s):
    - name: GOOGLE_OAUTH_ACCESS_TYPE
      value: "offline"
    - name: GOOGLE_OAUTH_PROMPT
      value: "consent"
    
  • Tested on a live GKE deployment with Google OAuth + BigQuery tools. Verified:
    • refresh_token stored in oauth_session table after login
    • Token auto-refreshed after >1 hour (log: "Successfully refreshed token for session ...")
    • No behavior change when env vars are unset

Screenshots or Videos

N/A — backend-only change with no UI impact.

Contributor License Agreement


🔄 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/22652 **Author:** [@ethan-l-geotab](https://github.com/ethan-l-geotab) **Created:** 3/13/2026 **Status:** ❌ Closed **Base:** `dev` ← **Head:** `fix/google-oauth-refresh-token-dev` --- ### 📝 Commits (1) - [`7bc28c6`](https://github.com/open-webui/open-webui/commit/7bc28c6552d4e1b3abf51b5eeaab9b7ab1a36411) fix: add configurable access_type and prompt for Google OAuth refresh tokens ### 📊 Changes **1 file changed** (+20 additions, -0 deletions) <details> <summary>View changed files</summary> 📝 `backend/open_webui/config.py` (+20 -0) </details> ### 📄 Description <!-- ⚠️ CRITICAL CHECKS FOR CONTRIBUTORS (READ, DON'T DELETE) ⚠️ 1. Target the `dev` branch. PRs targeting `main` will be automatically closed. 2. Do NOT delete the CLA section at the bottom. It is required for the bot to accept your PR. --> # Pull Request Checklist - [x] **Target branch:** Verify that the pull request targets the `dev` branch. - [x] **Description:** Provided below. - [x] **Changelog:** Included below. - [ ] **Documentation:** Environment variables to be documented in Open WebUI Docs. - [x] **Dependencies:** No new dependencies. - [x] **Testing:** Manually tested on a live deployment — verified refresh token is stored, auto-refresh works after 1 hour, and no behavior change when env vars are unset. - [x] **Agentic AI Code:** AI-assisted but fully human-reviewed and manually tested on a live Kubernetes deployment. - [x] **Code review:** Self-reviewed. Follows the same pattern as existing `GOOGLE_OAUTH_SCOPE` and `OAUTH_TIMEOUT` configurations. - [x] **Design & Architecture:** No new settings in the admin UI — env vars only, consistent with existing OAuth config pattern. - [x] **Git Hygiene:** Single atomic commit, rebased on `dev`. # Changelog Entry ### Description Without `access_type=offline` in the Google OAuth authorization request, Google only returns a short-lived access token (1 hour) with no `refresh_token`. The existing refresh logic in `OAuthManager._perform_token_refresh()` always bails at the `if not token_data.get("refresh_token")` check because no refresh token is ever stored. After ~55 minutes, the OAuth session is silently deleted from the database, breaking any functionality relying on `__oauth_token__` (tools, MCP servers with `system_oauth` auth) while the user's Open WebUI session remains active. This is a Google-specific issue: Google requires `access_type=offline` (a proprietary parameter not part of the OIDC spec) to issue refresh tokens. The OIDC discovery document gives no hint about this parameter, so authlib cannot add it automatically. This PR adds two new environment variables that populate `authorize_params` in the Google OAuth client registration, enabling operators to opt in to refresh token support. ### Added - `GOOGLE_OAUTH_ACCESS_TYPE` environment variable (default: `""`) — set to `"offline"` to request refresh tokens from Google - `GOOGLE_OAUTH_PROMPT` environment variable (default: `""`) — set to `"consent"` to force re-consent and guarantee a fresh refresh token for users who previously authorized the app ### Changed - `google_oauth_register()` in `config.py` now conditionally includes `authorize_params` when either env var is set (empty values are filtered out) ### Deprecated - N/A ### Removed - N/A ### Fixed - Google OAuth sessions no longer expire and get deleted after 1 hour when `GOOGLE_OAUTH_ACCESS_TYPE=offline` is configured - The existing token refresh logic (`OAuthManager._perform_token_refresh()`) now functions as intended for Google OAuth ### Security - Refresh tokens are stored encrypted (Fernet) in the existing `oauth_session` table, consistent with how all other OAuth tokens are stored - No change to default behavior — both env vars default to empty, preserving existing behavior for all deployments ### Breaking Changes - None. Both env vars default to empty, so no behavior change for existing deployments. --- ### Additional Information - **Why not default to `offline`?** To avoid changing behavior for existing deployments. Operators can opt in by setting `GOOGLE_OAUTH_ACCESS_TYPE=offline`. - **Why is `prompt` separate?** Google only returns a refresh token on the first authorization. For users who previously authorized the app, `prompt=consent` forces re-consent. This can be set temporarily and removed once all users have re-authenticated. - **Usage example (Helm/K8s):** ```yaml - name: GOOGLE_OAUTH_ACCESS_TYPE value: "offline" - name: GOOGLE_OAUTH_PROMPT value: "consent" ``` - Tested on a live GKE deployment with Google OAuth + BigQuery tools. Verified: - `refresh_token` stored in `oauth_session` table after login - Token auto-refreshed after >1 hour (log: `"Successfully refreshed token for session ..."`) - No behavior change when env vars are unset ### Screenshots or Videos N/A — backend-only change with no UI impact. ### Contributor License Agreement - [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. --- <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-04-20 06:43:05 -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#26798