Skip to content

fix: accept offline_access OAuth scope for MCP refresh clients#2630

Open
rohanpatel2002 wants to merge 1 commit into
supabase:masterfrom
rohanpatel2002:fix/oauth-offline-access-scope
Open

fix: accept offline_access OAuth scope for MCP refresh clients#2630
rohanpatel2002 wants to merge 1 commit into
supabase:masterfrom
rohanpatel2002:fix/oauth-offline-access-scope

Conversation

@rohanpatel2002

Copy link
Copy Markdown

What kind of change does this PR introduce?

Bug fix

What is the current behavior?

The OAuth 2.1 authorization server already issues refresh tokens on the authorization-code grant and supports the refresh_token grant. However, offline_access is not in the supported scope allowlist (SupportedOAuthScopes), so:

  1. GET /oauth/authorize?...&scope=openid%20offline_access fails with error=invalid_request / unsupported scope: offline_access
  2. /.well-known/oauth-authorization-server advertises scopes_supported: ["openid","profile","email","phone"] without offline_access

MCP clients (Copilot Studio, ChatGPT, and similar) often require offline_access to be advertised and granted before they will use refresh tokens. Without it, they hold unused refresh tokens, access tokens expire after ~1 hour, and users are forced to re-authenticate.

Fixes #2628

What is the new behavior?

offline_access is added to SupportedOAuthScopes (accept-and-ignore). Because authorize validation and discovery metadata both use that shared list:

  • Authorize requests that include offline_access succeed
  • Discovery metadata includes offline_access in scopes_supported

No change to token issuance: refresh tokens were already issued unconditionally when configured.

Additional context

Single-source change in internal/models/oauth_scope.go, with a unit test asserting IsSupportedScope("offline_access"). Happy to adjust if maintainers prefer a different approach. Thank you for reviewing.

@rohanpatel2002
rohanpatel2002 requested a review from a team as a code owner July 20, 2026 15:08
Copilot AI review requested due to automatic review settings July 20, 2026 15:08

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@cstockton

Copy link
Copy Markdown
Contributor

I think supporting the scope or ability to define custom scopes is an option, but would require platform work / configuration beyond this auth pr.

In it's current I don't think we could accept it as it would become the new default for all customers, which may have broader security implications. I'll let @cemalkilic chime in on this.

@alana-datum

Copy link
Copy Markdown

Datum here (filed #2628) — thanks for taking a look, @cstockton. Opt-in per-project works perfectly for us; we're not asking for this as a global default. A per-project config toggle fully addresses the security concern — we'd only ever enable it deliberately on our own project.

The narrow need: MCP clients (Copilot Studio, ChatGPT, claude.ai) only use the refresh token they already receive when offline_access is advertised in scopes_supported and accepted at /oauth/authorize. Without it, connections hard-expire ~hourly and users must re-authenticate. Since GoTrue already issues and honors refresh tokens unconditionally, even accept-and-ignore behind a per-project flag would unblock us.

Happy to test against a preview build whenever useful. Thanks both!

@cemalkilic

Copy link
Copy Markdown
Contributor

Thanks for raising it @alana-datum and for the contribution @rohanpatel2002!
Since requesting the offline_access scope remains optional, this doesn’t introduce any backward-compatibility issues. We already default to issuing refresh tokens, so this change doesn’t alter the existing behavior.

@rohanpatel2002 Could you update/rebase the master branch?

@rohanpatel2002
rohanpatel2002 force-pushed the fix/oauth-offline-access-scope branch from b3b8b4a to bfc329f Compare July 24, 2026 15:32
@rohanpatel2002

Copy link
Copy Markdown
Author

Thanks @cemalkilic — I’ve rebased this branch onto the latest master.

Quick recap of the change: offline_access is now in SupportedOAuthScopes (accept-and-ignore). Authorize validation and discovery metadata both use that list, so MCP clients that require the scope can proceed. Refresh-token issuance is unchanged — GoTrue already issues refresh tokens when configured, and requesting offline_access remains optional for clients that don’t need it.

No other code changes in this update; happy to adjust further if anything else comes up in review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OAuth 2.1 server: offline_access scope rejected at /oauth/authorize — MCP clients never use their refresh tokens (hourly forced re-auth)

5 participants