Skip to content

supabase link / projects api-keys: 403 insufficient privileges, but identical token succeeds via direct API call #6392

Description

@snoutly-vkm

supabase link / supabase projects api-keys fail with "insufficient privileges" while the identical token succeeds via direct API call

Bug report

supabase link (and supabase projects api-keys) fail with an "insufficient privileges" error, while the exact same personal access token, hitting the equivalent Management API endpoint, succeeds via a plain curl call.

Environment

  • CLI version: 2.116.0 (also reproduced on 2.107.0 before upgrading)
  • OS: macOS (Darwin 25.6.0)
  • Install method: Homebrew
  • Org plan: Pro, Owner role, billing/payment method on file

Steps to reproduce

supabase link --project-ref <ref>

Output:

{"_tag":"Error","error":{"code":"LegacyLinkProjectStatusError","message":"Unexpected error retrieving remote project status: {\"message\":\"Your account does not have the necessary privileges to access this endpoint. For more details, refer to our documentation https://supabase.com/docs/guides/platform/access-control\"}"}}

supabase projects api-keys --project-ref <ref> fails the same way.

Proof the token itself is fine

Using the same SUPABASE_ACCESS_TOKEN the CLI is resolving (verified via env var, not --profile, see below), a direct call to the Management API succeeds:

curl -s -o /dev/null -w "%{http_code}\n" -X GET \
  "https://api.supabase.com/v1/projects/<ref>" \
  -H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN"
# => 200

Same token, same project, same account — CLI rejects it, raw REST call accepts it.

What we ruled out

  • Token scope — token has full scope, confirmed via the dashboard.
  • Org role — Owner.
  • Billing — payment method on file, no past-due invoices.
  • Plan tier — Pro.
  • CLI version — reproduced on both 2.107.0 and the latest 2.116.0 at time of filing.
  • Local CLI state/cache — deleted ~/.supabase/profile and other local CLI state, re-authenticated from scratch, still reproduces.
  • --profile isolation — also found that --profile doesn't appear to isolate credentials as expected (logging a token under an unrelated profile name still authenticated as the real account), so we're resolving the token via SUPABASE_ACCESS_TOKEN env var instead, not --profile. Not certain this is related to the 403, flagging in case it's the same root cause (e.g. profile/account resolution picking the wrong context internally before the privilege check).

Impact

Can't use supabase link / supabase db push / supabase projects api-keys at all against this project. Working around it by scripting equivalent calls directly against the Management API (POST /v1/projects/{ref}/database/query), which work fine and confirms the backend/account itself has no permission issue — this looks CLI-internal.

Activity

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions