Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

RBAC roles, actions & resources

The control-plane API authorizes every request against a set of rights. A right is an action on a resource, optionally scoped to a site. A token carries one or more granted roles; a role expands to a set of rights. A request is allowed when a held right satisfies the right the request requires.

For issuing and verifying tokens, see Bootstrap authentication and Make a scoped CI deploy token; for the design, see Authentication & authorization.

Actions

ActionMeaning
readRead and list (GET endpoints).
writeMutate configuration: site config, aliases, domain verification, cache.
deployShip content: create and activate deployments, upload blobs.
adminFull control of the resource.

Only admin implies the others: a held admin right on a resource satisfies a required read, write, deploy, or admin on that same resource. The other three actions are independent. Implication is per-resource — admin on tokens does not satisfy any right on site.

Resources

Only site is target-scoped (the target is a site name); the other five are global.

ResourceScopedGoverns
sitesitePer-site deployments, config, aliases, domain verification, per-site observability.
blobsglobalContent-addressed blob uploads.
tokensglobalAPI token management.
certsglobalTLS certificate status.
cacheglobalCache invalidation.
systemglobalMetrics, prune, scrub, site listing, cluster membership, authz policy.

Default roles

The built-in policy defines five roles. A grant marked (site) binds to the role instance’s target; (any) is a global right.

RoleScopedGrants
adminglobaladmin on every resource.
publishersiteread, write, deploy on site (site); deploy on blobs (any).
deployersiteread, deploy on site (site); deploy on blobs (any). No config write.
viewersiteread on site (site).
operatorglobalread on system (any); read on certs (any); write on cache (any). No site access.

An unknown role name grants nothing — it is ignored, not an error.

Scoping

A granted role is written <role> (global) or <role>:<site> (bound to one site). The suffix after the first : is the target site; an empty suffix parses as global.

SpecInterpretation
adminGlobal admin.
publisher:blogpublisher bound to site blog.
viewer:docsviewer bound to site docs.

Granting a site-scoped role without a target (e.g. publisher with no :site) drops its site rights — a global publisher grants only its blobs right. Site matching is exact; a global (wildcard) grant covers every site.

A token carries a list of granted roles; the rights it confers are the union of each role’s expanded rights. A token minted with --role publisher:blog --role viewer:docs may write blog, read docs, and upload blobs.

Request-to-right mapping

Each control-plane endpoint requires exactly one right. A few endpoints require no right and are gated by their own single-use credential instead. Any unmapped /api/* path falls through to system · admin (deny-safe), so a narrow token can never reach an ungated action.

MethodPathRequired right
POST/api/auth/exchangenone (carries an IdP JWT)
GET/api/auth/whoaminone (any valid token)
POST/api/tokens/bootstrapnone (bootstrap secret)
POST/api/cluster/joinnone (single-use join token)
PUT/api/blobs/<hash>blobs · deploy
GET/api/sitessystem · read
POST/api/sites/<site>/deploymentssite · deploy
GET/api/sites/<site>/deployments[/<id>]site · read
POST/api/sites/<site>/deployments/<id>/activatesite · deploy
GET/api/sites/<site>/configsite · read
PUT/api/sites/<site>/configsite · write
PUT/DELETE/api/sites/<site>/aliases/<name>site · write
POST/DELETE/api/tokens[/<id>]tokens · admin
GET/api/certscerts · read
POST/api/cache/invalidatecache · write
GET/api/metricssystem · read
GET/POST/api/prune, /api/scrubsystem · admin
any/api/authz/*system · admin
anyother /api/*system · admin (deny-safe)

The policy document

The role-to-rights mapping is data, stored as JSON at the KV key authz/policy (schema v1). When the key is absent the built-in default above applies. A replacement is validated server-side and rejected if invalid, so a bad policy cannot brick the control plane. Editing it requires an admin token:

boatramp auth policy get              # print the active policy as JSON
boatramp auth policy set policy.json  # validated server-side before storing