How authorization works
- Every protected route demands a scope.
POST /v1/runsdemandsruns_write, for example. Creating a service-account key demandsmembers_writeon top ofkeys_write. - A credential carries a set of scopes. An API key carries the scopes it was created with. A console session carries the scopes of your role.
- If the credential lacks the route’s scope, the request is refused with
403 scope_deniedand the message names the missing scope.
error.code, and read the scope name from the message when you need to show it to a person.
The nine scopes
Scope names are snake_case, exactly as below, in requests, responses and error messages.Roles and the scopes they hold
Your role in an organization decides which scopes your console session holds, and so which scopes you can put on a key you create.
A role that is not in this table holds no scopes, so every scoped route answers
403 scope_denied.
What that means in practice:
- Only
ownerandadminholdmembers_write, so only they can create a service-account key. owner,adminandbillingholdbilling_write, so only they can buy credits or change auto-recharge.- A
membercan send runs and manage keys but cannot change billing. - A
viewercan read runs, keys, usage and balance, and cannot create anything.
Rules for a key’s scopes
The creator ceiling applies to whatever credential makes the call. A key that holds
keys_write and runs_read can create keys with keys_write, runs_read or both, and nothing else.
Least-privilege scope sets
Start from the smallest set that works, and add a scope only when a request returns403 scope_denied for a route the process really needs.
Other habits that keep the blast radius small:
- One key per process and per environment. A staging key should never be able to spend production credit.
- Never give
keys_writeto a key that also runs production traffic. A key withkeys_writecan revoke your other keys, and a rotation returns the rotated key’s new secret. - Give
runs_writeandbilling_writeonly where needed. They are the two scopes that spend money.
runs_write, runs_read, keys_read, keys_write, usage_read, billing_read). To create a key with members_read, members_write or billing_write, use POST /v1/keys.
Principal: who a key acts as
Each key has aprincipal, {"type": "user" | "service_account", "id": "..."}, which records who the key acts as. You set it with the optional principal field on POST /v1/keys.
The service-account
id is a label you choose, such as svc-nightly-batch. OpenType does not keep a separate list of service accounts. Whatever the principal, the key’s scopes still cannot exceed yours, and created_by always records who created the key.
Use a service-account key for keys that belong to a system rather than a person, so the principal on each key in GET /v1/keys shows which keys belong to workloads.
Errors
Related
- Scopes reference - every route and the scope it demands.
- Organizations and roles - where roles come from.
- Console API keys - the scope sets offered when you create a key in the console.
- scope_exceeds_creator - the full entry for the creator ceiling.
- API key security - store, revoke and rotate the keys you create.