Skip to content

Permissions & capabilities

Access on the ingest plane is capability-based. A key (or MCP token) is either an admin superuser or a set of grants, each binding a set of capabilities to a target.

CapabilityAllows
publishcreate/replace sites — POST /ingest/sites
unpublishsoft-delete sites — DELETE /ingest/sites/… (files kept in quarantine)
rollbacklist revisions and restore a previous version, or promote a chosen revision — GET/POST /ingest/sites/…/revisions[/rollback]
patchedit site metadata — PATCH /ingest/sites/…
purgepermanently destroy a quarantined site — POST /ingest/sites/…/purge

Unpublish and purge are intentionally separate: unpublish takes a site offline (recoverable within the TTL), while purge is irreversible. Automation that only tears down previews should hold unpublish; automation that also needs to destroy data permanently should hold both.

RoleGranted byCan do
Adminforward-auth allowlist or an admin keyeverything: manage keys + all capabilities on every site
Scoped keya key with one or more grantsonly the granted capabilities, confined to each grant’s target
Viewerany authenticated forward-auth userview the portal, GET /api/sites, and browse/download any site’s files and revisions (GET /api/sites/…/revisions…) — hidden sites stay admin-only

A grant’s target is either a group or a single site:

  • A group grant on docs owns the docs subdomain and everything beneath it: docs.<base> itself (the flat site group "", slug docs) and every site under *.docs.<base> (e.g. app.docs.<base> = group docs, slug app).
  • A site grant on docs/app is confined to exactly that one site (app.docs.<base>) — not its children, not its siblings.
  • A group grant with an empty target means all sites (global).

Targets are free-text (each label must match ^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$) — you don’t pre-register them.

  • Token format gtf_<base64url-32B>, shown in plaintext once at creation.
  • Only the SHA-256 hash is stored; lookups are constant-time.
  • A key may optionally expire (an instant, or never — the default); past it, the key is rejected like an unknown token.

Mint keys in the portal (API Keys view, admin only) or via the CLI. There is no bootstrap key: set GOTIFACTS_ADMIN_USERS, log in through your proxy, and create keys in the UI.

MCP connector tokens carry the same grant model: at the consent screen the approver picks a target (group subtree or single site) and the capabilities to allow, prefilled from GOTIFACTS_MCP_GROUP

  • publish. The connector can never act outside what was granted.