Skip to Content
APIScopes & Permissions

Scopes and Permissions

Every API key carries a set of scopes that decide which actions it may perform. A key with no scopes set has full access; a scoped key is limited to the actions you grant it, so you can hand an agent or a deployed app a least-privilege credential instead of a full-access one.

Scopes are enforced on the redu.cloud API. A request that a key is not scoped for is rejected before it reaches your infrastructure.


Scope grammar

A scope is one of the following tokens. A key may combine several; access is granted if any of its scopes matches the requested action.

TokenGrants
*Full access (every action). This is the default when no scopes are set.
readEvery read (GET) action, on all resources.
writeEvery write (POST, PUT, PATCH) action, on all resources.
deleteEvery delete (DELETE) action, on all resources.
<resource>:*Every action on one resource, for example instance:*.
<resource>:<action>One specific action, for example backup:create.
<resource>:<verb>Shorthand for all same-verb actions on a resource, for example instance:read.

Resource names are singular (instance, volume, managed_postgres).


Discover the full catalog

The complete, always-current list of resources and actions is served at:

curl https://api.redu.cloud/v1/capabilities

The response lists every resource with its actions, the scope grammar, and the scopes your current key holds:

{ "auth": { "granted_scopes": ["backup:create", "backup:restore", "instance:read"], "scope_model": { "grammar": "\"*\" | \"read\" | \"write\" | \"delete\" | \"<resource>:*\" | \"<resource>:<action>\"", "method_verbs": { "GET": "read", "POST": "write", "PUT": "write", "PATCH": "write", "DELETE": "delete" } } }, "resources": [ { "type": "backup", "actions": ["create", "delete", "list", "restore"] }, { "type": "instance", "actions": ["create", "delete", "list", "action", "console-log"] } ] }

Because both the enforcement and this catalog are generated from the same source, what /v1/capabilities lists is exactly what is enforced.


Common resources

A representative subset. Use /v1/capabilities for the authoritative list.

ResourceExample actions
instancelist, create, action, delete, console-log
volumelist, create, get, attach, detach, delete
snapshotlist, create, delete
backuplist, create, restore, delete
security_grouplist, create, update, add-rule, remove-rule, delete
private_networklist, create, delete
dnslist, create, update, delete
deploymentlist, create, create-compose, get, delete
managed_postgreslist, create, get, delete
managed_redislist, create, get, delete
api_keylist, create, delete

Least-privilege examples

A backup automation key. Read instances, and create or restore backups, nothing else:

{ "name": "nightly-backups", "scopes": ["instance:read", "backup:read", "backup:create", "backup:restore"] }

A read-only monitoring key. See everything, change nothing:

{ "name": "monitoring", "scopes": ["read"] }

A deploy key for one app. Manage deployments and their managed database:

{ "name": "ci-deploy", "scopes": ["deployment:*", "managed_postgres:*"] }

Omit scopes entirely to create a full-access key (["*"]).


Creating API keys is itself a scope

Minting a new API key requires the api_key:create scope (or a full-access key). A scoped automation key that lacks it cannot create more keys, and a key can never grant scopes broader than its own creator’s. This keeps a leaked automation key from escalating itself to full access.

Create keys from a Console session, or from a key you have deliberately granted api_key:create.


Denied requests

When a key lacks the scope for an action, the API returns 403 with a stable insufficient_scope code:

{ "error": { "code": "insufficient_scope", "message": "This API key lacks the 'instance:delete' scope required for this request.", "required_scope": "instance:delete", "granted_scopes": ["backup:create", "backup:restore", "instance:read"] } }

This is distinct from 401, which means the key is missing, malformed, expired, or invalid. See Authentication for the 401 cases.


Existing keys keep working

Keys created before scopes existed, and keys created with the coarse read / write / delete presets, behave exactly as before. Granular resource:action scopes are opt-in, chosen when you create a key.

Last updated on