Scopes
Preview A scope is a single permission — one action on one resource. Every API key carries a set of them, and they’re the core of how managed.dev beats coarse host tokens: instead of one all-or-nothing credential, you grant exactly the actions a key needs and nothing more.
The grammar
Section titled “The grammar”Scopes follow the form product.resource:action. The product. segment is optional —
it namespaces the dynamic application layer (the WordPress and CMS-specific surface) that
generic platforms don’t expose at all.
sites:read # resource:actionsites:writeenvironments:writewp.plugins:write # product.resource:actionwp.cli:execdb:readTwo relations cut down how many scopes you list:
writeimpliesread. Grantingsites:writealso grantssites:read. You never need to list both.adminimplieswrite(and thereforeread).teams:admincoversteams:writeandteams:read.
Wildcards expand to a whole namespace: wp:* grants every WordPress scope the runtime
advertises; * grants everything — except the isolated scopes below, which no
wildcard ever includes.
The isolation rule
Section titled “The isolation rule”Three scopes are dangerous enough that they’re excluded from every wildcard and every preset. You can only grant them explicitly, one at a time:
| Scope | What it unlocks |
|---|---|
credentials:read / :write |
Reveal SFTP/SSH/DB credentials and magic-link SSO; rotate secrets. |
exec:raw |
Run arbitrary raw shell — the keys to the kingdom. |
keys:write |
Mint and rotate other API keys. |
So a * key — about as broad as you can mint — still cannot reveal an SFTP password, run
a raw shell, or create new keys. Those require deliberate, single grants. This is the line
that keeps a broad automation key from quietly becoming a root credential. See the
security model for why this boundary holds.
Down-scoping: the triple intersection
Section titled “Down-scoping: the triple intersection”A scope grants nothing on its own — it only ever narrows what the key’s owner could already do. Effective permission on any request is the intersection of three things:
effective = perms(RBAC role) ∩ scopes(key) ∩ resource-constraint(key)perms(RBAC role)— what the principal that minted the key is allowed to do under their team role. A key minted by abilling-only member can never deploy, no matter which scopes it lists.scopes(key)— the scopes you granted at mint time.resource-constraint(key)— the optional team / project / site the key is pinned to.
The headline consequence: a key can never exceed its owner. Scopes can only subtract. This is the same mental model as Cloudflare and Stripe scoped tokens, and it’s why a narrowly-minted key is safe to hand to CI or a contractor — it’s structurally incapable of escalating past the person who created it. Keys are additionally forced to a non-admin role, so there is no admin scope at all; see the security model.
Runtime-gated scopes
Section titled “Runtime-gated scopes”The product. scopes — wp.*, db:*, cron:* — are only grantable and meaningful
where the runtime advertises the matching capability. wp.plugins:write does nothing on a
static site because a static site has no plugins. Clients shouldn’t hard-code
if runtime == "wordpress"; they should ask the site what it can do via
capability discovery and grant scopes accordingly.
A call against a route the runtime structurally can’t perform returns 404 (the
capability isn’t there); a route that exists but this runtime can’t fulfil returns
409 capability.unsupported. Both are covered in
capability discovery.
Common scopes
Section titled “Common scopes”A representative slice — the full list lives in the scope catalog.
| Scope | Gates | Runtime gate |
|---|---|---|
sites:read / :write |
Site get and config reads; create, restart, config writes. | always |
environments:write |
Create, delete, refresh, reset, suspend, resume environments. | env-capable |
deployments:write |
Trigger builds, promote, roll back. | always |
domains:write |
Domain and DNS-record management. | always |
backups:write |
Take backups; restore and download snapshots. | always |
observability:read |
Insights, logs, traces, requests, resource metrics. | always |
security:read / :write |
Blocks and malware overview; trigger scans, block IPs. | always |
jobs:read |
List and watch async jobs (incl. SSE). | always |
wp.plugins:write |
Install, activate, update, delete plugins. | runtime=wordpress |
wp.content:write |
Manage posts, pages, media; clone content. | runtime=wordpress |
cron:write |
Manage scheduled tasks. | runtime supports cron |
db:read |
Schema and read queries. | runtime has a managed DB |