Supabase change
Supabase personal access token scopes: how do I give an agent or CI a token for one project with only the permissions it needs?
Since scoping became generally available on September 28, 2026 (Supabase's post is from October 26), every personal access token you create in the Dashboard is scoped by default: you choose organizations or projects, Read or Read-write for each permission, and an expiry up to one year out, and a scoped token starts with sbp_fc. For a coding agent that only reads one project, scope it to that project, start from the No access preset rather than Read-only (which includes API key secrets), and turn on Database Read, which covers execute_sql for read-only queries, list_tables and generate_typescript_types in the Supabase MCP server. A token never has more access than your own role, its scope cannot be edited after creation, your old full-access tokens keep working with a Legacy badge, and the browser flow of supabase login still creates a full-access token today, so pass a scoped one with supabase login --token or SUPABASE_ACCESS_TOKEN. Checked against Supabase's post and docs on 2026-10-28.
Build a token for one agent
On the access tokens page, choose the resources (the Dashboard recommends a project-level scope), the permissions and the expiry. The review screen expands each permission into the Management API endpoints and MCP tools it covers, and shows a Low, Medium or High risk banner for the mix of reach and write access. Copy the value before you close the page: it is shown once.
Which permission each Supabase MCP tool needs
From the permission table in the Personal Access Tokens docs. Each tool checks before it runs and returns a tool error when the permission is missing. With Database Read, a SQL write through execute_sql returns a Postgres permission error rather than a 403.
execute_sql, list_tables, list_extensions,
generate_typescript_types Database (Read)
list_migrations Migrations (Read)
apply_migration Migrations (Read-write)
get_logs, query_logs Logs (Read)
get_advisors Advisors (Read)
list_edge_functions, get_edge_function Edge Functions (Read)
deploy_edge_function Edge Functions (Read-write)
get_project, get_project_url Project Settings (Read)
get_publishable_keys API Keys (Read)
list_projects Projects (account-wide) (Read)
create_branch, merge_branch Development or Production Branches (Read-write)
search_docs always availableA 403 with missing_permissions
When a Management API request lacks a permission, the 403 names it in a missing_permissions field. Check that your own role has that permission, then create a replacement token that includes it: scope and permissions are fixed at creation. A request for a project outside the token's scope gets a plain 403 with no field.
export SUPABASE_ACCESS_TOKEN="sbp_fc..."
# Database Read covers this endpoint
curl "https://api.supabase.com/v1/projects/your-project-ref/types/typescript" \
-H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN"
# needs Project Settings Read: HTTP 403 without it
curl -i "https://api.supabase.com/v1/projects/your-project-ref" \
-H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN"Scoped tokens with the Supabase CLI and in CI
Create the token in the Dashboard and pass it with supabase login --token, or set SUPABASE_ACCESS_TOKEN, which overrides any saved token and is the one to use in CI. supabase link needs Project Settings, API Keys and API Key Secrets, all Read. Database commands that connect with SUPABASE_DB_PASSWORD, such as supabase db push, are not limited by the token at all, so the database password is the real limit on what CI can change there.
supabase login --token sbp_fc...
# CI
export SUPABASE_ACCESS_TOKEN="sbp_fc..."
supabase link --project-ref your-project-refA token follows your own role
Every request checks both the token's scope and your current role. If you leave an organization or lose a permission, the token loses it too, and gets it back if your access returns; the token's detail view marks resources you can no longer reach. The Dashboard lets you add a permission your role lacks, but the token cannot use it until your role has it.
Find tokens committed to the repo
Personal access tokens start with sbp_, and scoped ones with sbp_fc. Search the repo and its history for both; a token found there should be deleted in the Dashboard and replaced with a scoped one.
grep -rn "sbp_" --exclude-dir=node_modules --exclude-dir=.git .
git log -p --all -S "sbp_" --onelineChecklist
Replace a full-access token
- 01List the tools that hold a Supabase token: coding agents, MCP configs, CI secrets, deploy scripts.
- 02For each one, create a token scoped to its project, with only the permissions its job needs and an expiry that matches it.
- 03Start an agent from the No access preset and add Database Read; add Migrations Read-write only if it applies migrations.
- 04Swap the new value into the tool or CI secret, run its usual job once, and read any missing_permissions in a 403.
- 05Delete the old token in the Dashboard once nothing uses it.
Related
Related guides
Sources
Official docs behind this checklist
Browse all launch guides · Read resources · How to make and check your next change
FAQ
FAQ for builders before launch
Do my existing Supabase access tokens stop working?
No. Existing tokens keep working until they expire or you delete them; full-access ones show a Legacy badge, and Create legacy token is still there.
Can I change the scope of a token later?
No. Scope and permissions are fixed at creation, so create a replacement token and swap it in.
Why not use the Read-only preset for an agent?
Because Read-only includes secrets such as API keys. Supabase suggests starting from No access and turning on Database Read.