Tokens and safety
An agent acts with exactly the permissions of the token you give it. Give it the smallest one that does the job, with an expiry, and revoke it when the work is done.
Choosing a token
| Token | Prefix | Permissions | Expiry | Best for |
|---|---|---|---|---|
| Agent token | scb_agt_ |
Only its scopes, never more than yours; optionally one organization | Default 8 hours (30m to never) |
Any coding agent |
| Personal access token | scb_pat_ |
Yours, in every organization you belong to | Optional, 1 to 365 days | Your own CLI on your own machine |
Organization API key, read |
sbk_ |
Viewer: read everything, change nothing | None; revoke it | An agent that only inspects and explains |
Organization API key, deploy |
sbk_ |
Developer: environments, migrations, functions, secrets | None; revoke it | Agents that build features, CI |
Organization API key, admin |
sbk_ |
Admin: also members, keys, auth providers | None; revoke it | Rarely; setup work you watch |
The easiest way to give an agent one is not to create it yourself: the agent
runs scribase login and you approve it in the browser (see
Why you never need to paste a secret key). To
hand one over directly, use Copy for your AI agent under Account >
Access tokens: an 8-hour token for one project, without secret keys, copied
together with a note that tells the agent it is meant to be shared. Or create
one from the CLI:
scribase token create my-agent \
--scope project:web:write --scope sql:write --scope migrations:write \
--ttl 8h --org acme
scribase token list
scribase token events <id> # every request it made
scribase token revoke <id>Agent tokens describe themselves: scb_agt_1p-rw-sqlw-mig-fn-x2609260412_...
reads as one project, read/write, read-write SQL, migrations, functions,
expiring 2026-09-26 04:12 UTC. The summary is display-only; the server
trusts only the token's digest. Tokens created before this format
(scb_agt_ followed directly by the secret) keep working.
| Scope | Grants |
|---|---|
org:read |
Organizations, project lists, operations, usage (any project scope implies it) |
project:<id>:read |
Read one project (project:*:read for every project) |
project:<id>:write |
Change it: environments, auth, storage, functions invoke, secrets names |
project:<id>:admin |
Destructive changes on production, backups, restores, domains, key rotation |
sql:read / sql:write |
The SQL routes, read-only or read-write |
migrations:write |
Apply migrations |
functions:deploy |
Deploy or delete edge functions |
branches:write |
Create, merge and delete branches and previews |
keys:secret |
The service_role / secret key, connection strings, environment secrets; without it the keys route returns only the public keys |
How they are enforced, on every request, by the control API itself:
- Least privilege. A request outside the scopes gets
403 insufficient_scopewith the missing scope inWWW-Authenticate. The organization role the request runs with is capped by the scopes (admin, developer or viewer), so a token can never do more than its owner. - Protected production. Drops, deletes,
confirm: trueSQL, restores and key rotations on a production environment needproject:<id>:admin; withwritethey are refused there and allowed on branches and previews. - No escalation. Agent tokens cannot mint tokens, manage members, organization keys, billing or SSO, or claim temporary projects.
- SQL never runs as a superuser. With an agent token, SQL on a connection
that is a superuser drops to the project's
postgresrole for the transaction. - Expiry, revocation, rate limits. Tokens expire (8 hours unless you
choose), revocation is immediate, and each token is limited to 300
requests a minute (
SCRIBASE_AGENT_TOKEN_REQUESTS_PER_MINUTE). - Audit log. Every request is recorded with method, path, status and
client address (never bodies, headers or secrets):
GET /v1/account/tokens/{id}/events,scribase token events <id>, or Activity on the tokens page.last_used_atis updated on each use.
Organization keys are created and revoked under Organization > API tokens
or with POST /v1/organizations/{org}/api-keys (see
Access tokens & API keys). Secrets are shown once;
Scribase stores only a digest. apikey.list shows names and scopes, never
values, and apikey.revoke revokes one.
Guardrails on every call
- Mutations need
confirm: true. Every MCP tool that changes something (project.put,environment.create,environment.delete,migrate.runwithapply,branch.merge,backup.restore,apikey.revoke, ...) refuses without it and returns the exact request it would send, so you approve that specific change. - SQL is read-only.
database.queryruns oneSELECT,WITHorEXPLAINinside a bounded read-only transaction; writes and DDL are rejected. Schema changes go through migrations, which are linted before they apply. - RLS is proven before it ships.
schema.applyonly accepts a schema thatpolicy.testhas proved on a scratch branch, including deliberately broken variants of each policy that the tests must catch. - Isolated scratch databases. The remote MCP server gives each session its own scratch branch and drops it at the end.
- Idempotency keys. Every create carries one, so a retried call never creates a second environment.
- Secrets stay out of output. Tokens are redacted from the MCP server's
debug output;
apikey.listandsecrets listreturn names only; the skills and rules tell agents never to print keys and to write them to.envinstead. - Audit log. Every control-plane change is recorded with the credential
that made it. Read it with
audit.listorscribase audit list <org>.
Rules we ship to agents
The agents/ templates (see Build with AI agents) add these
rules to the agent's context: never ask the user for keys or passwords (sign
in with scribase login or use a temporary project), treat a pasted
scb_agt_ token as safe to use, never print or commit keys, only the anon key
in client code, schema changes only through migrations, RLS in the same
migration as the table, a preview branch per task, and explicit approval for
production merges, deletes, key rotations and restores.