Skip to content

OAuth 2.1 Server (beta): GET /oauth/authorizations/{id} returns 400 when resource, offline_access, or a public client is used — blocks MCP connectors #2820

Description

@maiconbatistaaa

Bug report

  • I confirm this is a bug with Supabase, not with my own application.
  • I confirm I have searched the Docs, GitHub Discussions, and Discord.

Describe the bug

On a hosted project with the OAuth 2.1 Server (beta) enabled, the consent screen cannot load the authorization details. GET /auth/v1/oauth/authorizations/{authorization_id} returns 400 authorization request cannot be processed on the first and only request for a freshly created authorization.

Through a controlled matrix I isolated three independent triggers. Any one of them alone reproduces the 400.

This makes the OAuth Server unusable for MCP connectors (ChatGPT developer mode), because the MCP client sends resource (RFC 8707) and requests offline_access.

Controlled matrix

Same user, same redirect_uri, same PKCE S256, freshly generated authorization_id, single request per row.

Client type scope resource param Result
Confidential openid email profile no 200 OK - consent renders
Confidential openid email profile yes 400
Confidential openid email profile offline_access no 400
Confidential openid email profile phone offline_access no 400
Confidential openid email profile phone offline_access yes 400
Public (PKCE, no secret) openid email profile no 400

Only one combination works: confidential client + openid email profile + no resource.

Independent triggers, each sufficient on its own:

  1. Public client (token_endpoint_auth_method: none)
  2. offline_access scope
  3. resource parameter (RFC 8707)

openid, email, profile, phone and offline_access are all advertised in /auth/v1/.well-known/openid-configuration under scopes_supported.

To Reproduce

  1. Enable the OAuth 2.1 Server on a hosted project.
  2. Create an OAuth app (confidential, client_secret_basic).
  3. Send the user to:
GET https://<project>.supabase.co/auth/v1/oauth/authorize
  ?response_type=code
  &client_id=<client_id>
  &redirect_uri=<registered_uri>
  &scope=openid%20email%20profile%20offline_access
  &state=<state>
  &code_challenge=<S256_challenge>
  &code_challenge_method=S256
  1. Supabase redirects to the Authorization Path with ?authorization_id=<id>.
  2. The consent app calls supabase.auth.oauth.getAuthorizationDetails(<id>).
  3. Observe GET /auth/v1/oauth/authorizations/<id> -> 400 authorization request cannot be processed.
  4. Remove offline_access from scope -> the same request returns 200 and the consent screen renders.

Adding &resource=https://<mcp-server>/mcp in step 3 reproduces the 400 even with minimal scopes. Using a public client reproduces it as well.

Masked authorization_ids that returned 400: kv34..., 4szda..., 5wiuz....

Expected behavior

getAuthorizationDetails() should return the pending authorization for any scope listed in scopes_supported, for public clients using PKCE, and when resource is present, since resource is part of the OAuth/MCP flow.

Actual behavior

400 authorization request cannot be processed on the first request, suggesting the authorization is not left in a pending state when any of the three conditions is met.

System information

  • Hosted Supabase project, region sa-east-1
  • OAuth 2.1 Server: enabled (beta)
  • Allow Dynamic OAuth Apps: disabled
  • Authorization Path: /#/oauth/consent (hash router, see OAuth 2.1 authorize redirects to invalid /oauth/consent path on hosted projects #2408)
  • Consent app: Vite + React SPA, @supabase/supabase-js 2.116.0
  • User has an active session; authorization_id is fresh and used once
  • Verified single request (no duplicate fetch) and current bundle (stale service worker cleared)

Additional context

In the tested ChatGPT MCP connector configuration, ChatGPT sends resource and requests offline_access. With that configuration there is no combination that completes the flow against the Supabase OAuth Server today.

Related: #2408 (authorize redirects to invalid /oauth/consent path on hosted projects).

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions