Roles and permissions reference
A person has one role in each organization: viewer, member, admin or owner. The role decides which permissions the person holds. This page lists every permission and the roles that hold it. It also covers the scopes of API keys and personal access tokens.
Roles are cumulative. Each role holds every permission of the roles below it, and then more. Spanlight checks one permission per action. It does not compare roles for ordinary actions, so apart from the owner rule below, this table is the whole rule.
Permissions by role
Section titled “Permissions by role”A role that holds a permission shows Yes.
| Permission | Allows | Viewer | Member | Admin | Owner |
|---|---|---|---|---|---|
org:read |
Reading the organization, its members and its projects | Yes | Yes | Yes | Yes |
project:read |
Reading a project’s data, such as traces, metrics and prompts | Yes | Yes | Yes | Yes |
key:create |
Creating project API keys | No | Yes | Yes | Yes |
key:revoke_own |
Revoking the keys you created | No | Yes | Yes | Yes |
export:create |
Requesting trace exports | No | Yes | Yes | Yes |
scores:write |
Adding scores. Deleting a score someone else added needs project:write |
No | Yes | Yes | Yes |
annotations:write |
Working in annotation review queues | No | Yes | Yes | Yes |
prompts:write |
Creating prompts and prompt versions | No | Yes | Yes | Yes |
datasets:write |
Creating and changing datasets and their items | No | Yes | Yes | Yes |
experiments:run |
Running experiments and playground runs | No | Yes | Yes | Yes |
insights:feedback |
Saying whether a Doctor insight was right or wrong, and withdrawing that vote | No | Yes | Yes | Yes |
key:revoke_any |
Revoking any project key | No | No | Yes | Yes |
project:write |
Changing project settings, such as retention | No | No | Yes | Yes |
project:delete |
Deleting a project | No | No | Yes | Yes |
member:manage |
Inviting members and changing or removing their roles | No | No | Yes | Yes |
org:update |
Renaming the organization | No | No | Yes | Yes |
audit:read |
Reading and downloading the audit log | No | No | Yes | Yes |
gateway:write |
Changing gateway routes, keys and price overrides | No | No | Yes | Yes |
alerts:write |
Managing alert channels, rules and budgets | No | No | Yes | Yes |
insights:manage |
Managing the Doctor’s insights | No | No | Yes | Yes |
evaluators:write |
Creating and running evaluators | No | No | Yes | Yes |
datasets:lock |
Locking and unlocking a dataset. A locked dataset refuses every change to its items | No | No | Yes | Yes |
billing_sources:manage |
Adding, editing, re-keying and deleting billing sources: provider accounts connected with an admin key or as CSV uploads. Any member can read them | No | No | Yes | Yes |
org:delete |
Deleting the organization | No | No | No | Yes |
org:security |
Requiring two-factor authentication for the organization | No | No | No | Yes |
credentials:manage |
Managing the provider credentials the gateway uses | No | No | No | Yes |
A person who is not a member of an organization gets 404 NOT_FOUND for it, not 403. That way Spanlight does not reveal which organizations exist. See Tenancy and data isolation.
Who can assign roles
Section titled “Who can assign roles”Owners and admins hold member:manage, so both can invite people and change roles. One rule limits admins: only an owner can grant the owner role, change an owner’s role or remove an owner. An admin who tries gets 403 FORBIDDEN.
An organization must keep at least one owner. A request that would remove the last one gets 409 LAST_OWNER.
Any member can leave an organization. Leaving is still subject to the last-owner rule.
API key scopes
Section titled “API key scopes”A project API key does not have a role. It has scopes, chosen when the key is created. A key keeps its scopes for its lifetime.
| Scope | Allows |
|---|---|
ingest:write |
Sending traces to POST /v1/traces and POST /v1/otlp/traces. This is the default scope of a new key. |
traces:read |
Reading the dashboard routes for the key’s own project. |
scores:write |
Sending scores to POST /v1/scores. |
prompts:read |
Fetching a prompt from GET /v1/prompts/{name}. |
A key used outside its scopes gets 403 KEY_SCOPE. A key past its expiry gets 401 KEY_EXPIRED. A key can reach only its own project. See API keys, tokens and administration for how to create and revoke keys.
Personal access tokens
Section titled “Personal access tokens”A personal access token has no permissions of its own. It acts as its person, so the person’s current role applies on every request. The token adds one limit through its scope:
- A write token can do whatever the person’s role allows.
- A read token can use only the permissions that read:
org:read,project:readandaudit:read. Any change gets403 TOKEN_SCOPE.
A token cannot use routes that need a signed-in browser session. Those routes answer 403 SESSION_REQUIRED.
Related pages
Section titled “Related pages”- API keys, tokens and administration: create keys and tokens, and set their scopes.
- Tenancy and data isolation: how roles, projects and row-level security fit together.
- Limits reference: rate limits for keys and tokens.
- Error codes: what
FORBIDDEN,KEY_SCOPEandTOKEN_SCOPEmean and how to fix them. - Accounts and sign-in: invitations, two-factor authentication and membership.