Skip to content
Shortspan

Search documentation

Find a page by title, section, or summary.

Roles and permissions

The four roles, how a permission decision is reached, and every gate a request passes through.

The four roles

Strictly ordered. Each includes everything below it, which means a comparison is "at least this role" rather than a set membership test.

text
viewer  <  developer  <  admin  <  owner
RoleAdds

viewer

See that resources exist, and their metadata. No values, no credentials.

developer

Read and write secrets, use every registered resource, execute runbooks, request access.

admin

Register infrastructure, manage members, approve access and executions, read the audit log.

owner

Billing, subscription changes, and deleting the workspace.

A fifth name, requester, appears on access-request endpoints. It is not a role - it is a floor meaning "any member", used where the point is that anyone may ask.

How a decision is reached

  1. 1

    Which workspace is this request acting in?

    Resolved from the account's current workspace, or from the organization named in the route. No membership means no role at all - not a default one.

  2. 2

    What is their workspace role?

    From the membership record. This is their baseline everywhere.

  3. 3

    Is there a project override?

    A per-project membership replaces the workspace role for that project. It can lower as well as raise.

  4. 4

    Is there an active temporary grant?

    An approved, unexpired access request can raise the effective role for its project until it expires.

  5. 5

    Does the token permit it?

    Abilities narrow the result. They never widen it - a viewer with secrets:reveal still reveals nothing.

  6. 6

    Does the plan include it?

    Feature and limit gates run last, so a permitted action on an unentitled plan returns a paywall rather than a permission error.

The gates

Every check is middleware, applied at the route. A controller cannot forget to call one, and reading the route file tells you exactly what protects an endpoint.

GateChecksRefusal

secure.transport

TLS

426 HTTPS_REQUIRED

cli.version

Client version not withdrawn

403 CLI_VERSION_BLOCKED

auth:sanctum

Token valid and unrevoked

401 UNAUTHENTICATED

account.active

Account and workspace not suspended

403 account_suspended

onboarded

A workspace exists to act in

409 ONBOARDING_REQUIRED

shortspan.role:<role>

Workspace role, for console routes

403

org.member:<role>

Membership of a named organization

403 PERMISSION_DENIED

project.permission:<role>

Effective role on a project

403 PERMISSION_DENIED

plan.feature:<slug>

Tier includes the feature

402 FEATURE_NOT_IN_PLAN

plan.limit:<key>

Under the tier's cap

402 PLAN_LIMIT_REACHED

throttle:api-reveal

Plaintext request rate

429

Why a forbidden resource is a 404

Listing endpoints return only what you can see, so a resource you have no access to is absent rather than forbidden. Fetching one directly returns 404 for the same reason.

A 403 on a resource you cannot see would confirm it exists, which is enough to enumerate another team's infrastructure by alias. The two cases are deliberately indistinguishable.

The platform control plane

Platform administration is a separate identity system, not a role in this hierarchy. Being a workspace owner grants nothing there, and being a platform admin grants nothing inside a customer workspace.

It has its own login, its own session store, its own middleware group, its own audit log, and step-up authentication for sensitive operations. Its abilities are metadata-only by construction - see Security model.

Self-hosting means you operate it. See Running it.

In practice

  • Invite as developer by default. Admin is for people who register infrastructure and approve access.

  • Use per-project overrides for the exceptions rather than promoting someone workspace-wide.

  • Keep production a separate project, so developer access to staging is not developer access to production.

  • Scope tokens to the job. A deploy pipeline rarely needs more than secrets:read.

  • Prefer a temporary grant over a permanent promotion. It expires without anyone remembering to remove it.

Something here wrong or missing? Tell us.