From 0eb08cb9f09fc24de96e00cf6cde4321cd639290 Mon Sep 17 00:00:00 2001 From: Wen Bo Xie Date: Mon, 28 Sep 2026 10:43:18 +0900 Subject: [PATCH] docs: prepare scoped personal access tokens docs for GA (#50839) Scoped personal access tokens are leaving alpha. Remove the pre-GA framing and update pages that assumed every token carries full account access. - Personal Access Tokens guide: remove the public alpha / early access admonition. Add a section on using a scoped token with the Supabase CLI: the browser flow of `supabase login` creates a classic token, while SUPABASE_ACCESS_TOKEN or `supabase login --token` uses a scoped one, and commands that connect with the database password aren't limited by the token's permissions. - Management API introduction: replace "PATs carry the same privileges as your user account" with the scoped vs. classic distinction and link to the guide's permission tables. - MCP guide: the CI setup now asks for a scoped token limited to the connected project and links to the MCP tool permissions table. - API keys guide: replace the internal "fine-grained token" permission ID with the names shown in the dashboard (API Keys, Read), and note that `reveal=true` in the example also needs API Key Secrets (Read). - Managing environments: recommend a scoped token for the GitHub Actions deploy workflow. --- apps/docs/content/guides/ai-tools/mcp.mdx | 4 +-- .../deployment/managing-environments.mdx | 4 ++- .../guides/getting-started/api-keys.mdx | 2 +- .../platform/personal-access-tokens.mdx | 25 +++++++++++++------ apps/docs/docs/ref/api/introduction.mdx | 4 +-- .../AccessTokens/MigrationAdmonition.tsx | 16 +++++++----- 6 files changed, 35 insertions(+), 20 deletions(-) diff --git a/apps/docs/content/guides/ai-tools/mcp.mdx b/apps/docs/content/guides/ai-tools/mcp.mdx index abfc36d5f60..d22d725889b 100644 --- a/apps/docs/content/guides/ai-tools/mcp.mdx +++ b/apps/docs/content/guides/ai-tools/mcp.mdx @@ -133,11 +133,11 @@ There are some situations where you might want to manually authenticate the MCP ### CI environment -To authenticate the MCP server in a CI environment, you can create a personal access token (PAT) with the necessary scopes and pass it as a header to the MCP server. +To authenticate the MCP server in a CI environment, create a scoped personal access token (PAT) and pass it as a header to the MCP server. 1. Production projects can contain sensitive data. Before connecting one, scope the server to that project, enable [read-only mode](#configuration-options), restrict the available feature groups, and review the [security risks](#security-risks). -1. Navigate to your Supabase [access tokens](/dashboard/account/tokens) and generate a new token. Name the token based on its purpose, e.g. "Example App MCP CI token". +1. Navigate to your Supabase [access tokens](/dashboard/account/tokens) and generate a new token. Name the token based on its purpose, for example "Example App MCP CI token". Scope it to the project the server connects to, and grant only the permissions your enabled tools need. See [MCP tools](/docs/guides/platform/personal-access-tokens#mcp-tools) for the permission each tool requires. 1. Pass the token to the `Authorization` header in your MCP server configuration. For example if you are using [Claude Code](https://docs.claude.com/en/docs/claude-code/github-actions), your MCP server configuration might look like this: diff --git a/apps/docs/content/guides/deployment/managing-environments.mdx b/apps/docs/content/guides/deployment/managing-environments.mdx index 1054268b45d..c621aa4b5bf 100644 --- a/apps/docs/content/guides/deployment/managing-environments.mdx +++ b/apps/docs/content/guides/deployment/managing-environments.mdx @@ -161,10 +161,12 @@ You need a _new_ project for staging. A project which has already been modified The Supabase CLI requires a few environment variables to run in non-interactive mode. -- `SUPABASE_ACCESS_TOKEN` is your personal access token +- `SUPABASE_ACCESS_TOKEN` is a [scoped personal access token](/docs/guides/platform/personal-access-tokens) limited to the projects this workflow deploys to - `SUPABASE_DB_PASSWORD` is your project specific database password - `SUPABASE_PROJECT_ID` is your project specific reference string +The workflows below run `supabase link`, so grant the token **Project Settings**, **API Keys**, and **API Key Secrets**, all with **Read** access. + We recommend adding these as [encrypted secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets) to your GitHub Actions runners. Create the following files inside the `.github/workflows` directory: diff --git a/apps/docs/content/guides/getting-started/api-keys.mdx b/apps/docs/content/guides/getting-started/api-keys.mdx index 211ab9ec5b7..10d52353928 100644 --- a/apps/docs/content/guides/getting-started/api-keys.mdx +++ b/apps/docs/content/guides/getting-started/api-keys.mdx @@ -176,7 +176,7 @@ Pass the branch's own project ref to read the keys for a preview branch. A branc Use the Management API to fetch keys from your own tooling, such as a deploy script or an internal provisioning service. -Authenticate with a [personal access token](/dashboard/account/tokens). An OAuth application needs the `secrets:read` scope, and a fine-grained token needs the `api_gateway_keys_read` permission. Without either, the request returns 403 Forbidden. +Authenticate with a [personal access token](/dashboard/account/tokens). An OAuth application needs the `secrets:read` scope, and a [scoped personal access token](/docs/guides/platform/personal-access-tokens) needs the **API Keys** permission with **Read** access. To reveal key values with `reveal=true`, as the example below does, the scoped token also needs **API Key Secrets** with **Read** access. Without the required scope or permissions, the request returns 403 Forbidden. ```bash export PROJECT_REF="your-project-ref" diff --git a/apps/docs/content/guides/platform/personal-access-tokens.mdx b/apps/docs/content/guides/platform/personal-access-tokens.mdx index 9710b5d77f4..98de3ea3636 100644 --- a/apps/docs/content/guides/platform/personal-access-tokens.mdx +++ b/apps/docs/content/guides/platform/personal-access-tokens.mdx @@ -3,15 +3,9 @@ title: 'Personal Access Tokens' description: 'Scope personal access tokens to specific organizations, projects, and permissions' --- - - -Scoped personal access tokens are in **public alpha** and rolling out gradually. If you don't see the option to choose permissions when creating a token, your account doesn't have access yet. File a [support ticket](https://supabase.help) to get early access. - - - Personal access tokens (PATs) authenticate you to the [Management API](/docs/reference/api/introduction) and the tools built on it, like the Supabase CLI and the [MCP server](/docs/guides/ai-tools/mcp). They come in two flavors: -- **Classic tokens** carry your account's full access. That means every permission, on every organization and every project you belong to today, and on every one you create or join in the future. A classic token created a year ago can touch a project you created today. +- **Classic tokens**, shown with a **Legacy** badge in the dashboard, carry your account's full access. That means every permission, on every organization and every project you belong to today, and on every one you create or join in the future. A classic token created a year ago can touch a project you created today. - **Scoped tokens** carry only the organizations, projects, and permissions you choose. For example: read one project's database and view its logs, with no access to billing or organization settings. @@ -46,7 +40,22 @@ curl -i "https://api.supabase.com/v1/projects/your-project-ref/types/typescript" # Returns HTTP 403 ``` -The tables below list which permission unlocks which endpoints, and which permission each [MCP tool](#mcp-tools) requires, so you can grant exactly what a workflow needs. +To grant exactly what a workflow needs, see [Permission scopes](#permission-scopes) for the permission each endpoint requires and [MCP tools](#mcp-tools) for the permission each MCP tool requires. + +## Use a scoped personal access token with the Supabase CLI + +The browser flow of `supabase login` creates a classic token. To run the CLI with a scoped token instead, set it in the `SUPABASE_ACCESS_TOKEN` environment variable, or save it with `supabase login --token`. The environment variable takes precedence over any saved token, which also makes it the right choice for CI. + +For example, with a token granted **Projects (account-wide)** with **Read** access, `supabase projects list` lists the projects the token can reach: + +```bash +export SUPABASE_ACCESS_TOKEN="sbp_fc..." +supabase projects list +``` + +Commands that call the Management API fail with a permission error when the token lacks the required permission. `supabase link`, for instance, needs **Project Settings**, **API Keys**, and **API Key Secrets**, all with **Read** access. + +Database commands that connect with your database password, such as `supabase db push` with `SUPABASE_DB_PASSWORD` set, aren't limited by the token's permissions. A workflow that runs `supabase link` before `supabase db push` still needs the permissions `supabase link` requires. ## Permission scopes diff --git a/apps/docs/docs/ref/api/introduction.mdx b/apps/docs/docs/ref/api/introduction.mdx index c470a20ffdc..6f005cda88a 100644 --- a/apps/docs/docs/ref/api/introduction.mdx +++ b/apps/docs/docs/ref/api/introduction.mdx @@ -22,9 +22,9 @@ hideTitle: true There are two ways to generate an access token: 1. **Personal access token (PAT):** - PATs are tokens with a custom expiry that you manually generate to access the Management API. They are useful for automating workflows or developing against the Management API. PATs carry the same privileges as your user account, so be sure to keep it secret. + PATs are tokens with a custom expiry that you manually generate to access the Management API. They are useful for automating workflows or developing against the Management API. A scoped PAT can only reach the organizations, projects, and permissions you choose when creating it. A classic PAT, shown as Legacy in the dashboard, carries the same privileges as your user account. Prefer scoped PATs, and keep every token secret. - To generate or manage your personal access tokens, visit your [account](/dashboard/account/tokens) page. + To generate or manage your personal access tokens, visit your [account](/dashboard/account/tokens) page. See [Personal access tokens](/docs/guides/platform/personal-access-tokens) for the permission each endpoint requires. 2. **OAuth2:** OAuth2 allows your application to generate tokens on behalf of a Supabase user, providing secure and limited access to their account without requiring their credentials. Use this if you're building a third-party app that needs to create or manage Supabase projects on behalf of your users. Tokens generated via OAuth2 are short-lived and tied to specific scopes to ensure your app can only perform actions that are explicitly approved by the user. diff --git a/apps/studio/components/interfaces/Account/AccessTokens/MigrationAdmonition.tsx b/apps/studio/components/interfaces/Account/AccessTokens/MigrationAdmonition.tsx index 20b49f02a64..02965c577c6 100644 --- a/apps/studio/components/interfaces/Account/AccessTokens/MigrationAdmonition.tsx +++ b/apps/studio/components/interfaces/Account/AccessTokens/MigrationAdmonition.tsx @@ -17,13 +17,16 @@ export const MigrationAdmonition = () => { return ( - {/* Awaiting correct documentation link */} @@ -35,11 +38,12 @@ export const MigrationAdmonition = () => { >

- We recommend granting each new token the minimum access its integration needs. + Choose which organizations and projects each new token can reach, and what it can do + there. Grant only what its integration needs.

- Pre-existing tokens are marked with a Legacy badge and will continue to - work until expiry or deletion. + Tokens with full account access show a Legacy badge and keep working until + they expire or you delete them.