Version

Ability Catalogue

Every ability string a token can carry, how the catalogue mirrors the team permissions, what enforces it on the API today, and how to pick the right ones when minting.

Ability strings are the fine-grained permissions you tick when you mint a personal access token. Miss the one an endpoint or tool needs and the request returns TOKEN_MISSING_ABILITY, naming it in error.context.required_ability.

One string, every surface

A single ability, say project:create, is the source of truth in three places:

  1. The app, when a person presses "Create project": their role or group must carry the matching permission.
  2. The REST API, in the route middleware before the controller runs.
  3. The MCP server, inside the tool handler before the action runs.

An MCP tool requires exactly what its REST equivalent requires. Mint for the operations you intend to perform, never for the channel you intend to perform them over. A client connected to the MCP server by signing in acts as the person themselves and satisfies every ability their team role grants; this catalogue governs what a personal access token carries.

Format

<entity>:<action>, with : as the separator and - inside a multi-word entity or action: work-item:view-any, change-request:approve.

Most entities carry the five CRUD actions (view-any, view, create, update, delete), and some add named actions for the moments in their lifecycle that are not CRUD: epic:submit and epic:approve, sprint:start and sprint:close, release:freeze, release:publish and release:rollback. Three entities carry no CRUD at all:

  • team-member: membership is invited and removed rather than created and deleted, and update-role is its own action.
  • webhook-delivery: a delivery is a record of something that already happened, so it can only be listed, viewed and retry'd.
  • report, dashboard and activity: read-only, each with the single action read.

The catalogue

The catalogue mirrors the team permission catalogue one to one: every permission a role can grant is an ability a token can carry, plus the five extras below that exist only for tokens and agents. A machine-readable copy is served by the API host at /abilities.json once the catalogue export lands, regenerated on every deploy.

Families

FamilyEntities
Clientsclient
Projectsproject, project-member
Components and environmentscomponent, environment (+ deploy, freeze), repository
Project registrystakeholder, persona, glossary, data-entity, design-reference
Planningepic (+ submit, approve), work-item (+ transition, assign, rank), requirement (+ submit, approve), business-rule (+ submit, approve), use-case, raid, decision, link, baseline (+ freeze), approval (view-any, view, decide, withdraw, manage-policies), change-request (+ analyse, approve, verify)
Buildsprint (+ start, close), time-log (+ approve)
Testingtest-suite, test-case (+ approve), test-plan (+ approve), test-run (+ execute, sign-off)
Releases and deploymentsrelease (+ freeze, approve, publish, rollback), deployment (+ record, promote)
Maintenanceincident (+ command, resolve, publish-update), ticket (+ respond, convert), maintenance-window
Knowledge and documentsknowledge, document (+ render, finalise), import
Attachmentsattachment
Commentscomment (+ internal)
Reports and dashboardsreport:read, dashboard:read
Activity logactivity:read
AIai:use, ai:manage-budgets
Teamsteam, team-member (view-any, view, invite, remove, update-role)
Roles and groupsrole, group
API tokenstoken
Webhookswebhook-endpoint, webhook-delivery (view-any, view, retry)
Integrationsintegration:manage

Extras

Five abilities exist for tokens and agents only, outside the team permission catalogue:

AbilityWhat it opens
account:readGET /v1/me, the caller's notifications and alert destinations.
account:writeMarking the caller's notifications read and replacing their alert destinations.
mcp:useThe OAuth scope an MCP client is granted when a person signs in; it stands for their whole catalogue.
ci:deployA pipeline token that records deployments and nothing else.
ci:test-resultsA pipeline token that reports test runs and nothing else.

Enforced today

The REST API ships family by family as each phase of the product lands. Today these families have live endpoints, and every other ability is accepted on a token and gates nothing yet:

FamilyEndpoints
AccountGET /v1/me, GET /v1/me/notifications, the two marks, GET /v1/me/alert-destinations and its PUT.
TeamsGET /v1/teams, /teams/current, /teams/{team}, create, rename and delete; the roster, one member, the invitations, inviting, re-roling, removing and withdrawing.
Roles and groupsList, read, create, update and delete; PUT /v1/groups/{group}/members.
API tokensList, read, mint and revoke.
WebhooksEndpoints: list, read, register, pause, resume, rotate, test, delete. Deliveries: list, read, retry, retry dead. Event samples.
Activity logGET /v1/activity for a project, a client or a project member.
ProjectsGET /v1/projects and GET /v1/projects/{project}, read-only until the registry lands.

ai:use gates one kind of REST route: asking Heimdall for a quality review under a work item, a requirement or a business rule (POST …/quality-reviews), and the review_quality tool that does the same. Everything else Heimdall does runs in-app, and an outside agent drives Zuse Bifrost through the MCP server.

Choosing abilities when minting

Least privilege, in practice:

  1. Read-only tooling: the :view-any and :view abilities for the entities you read, and nothing else.
  2. A pipeline: ci:deploy or ci:test-results, confined to one project with a scope:project: entry.
  3. An assistant over MCP: every ability for the tools you want it to run. Start with reads; the tools reference maps each tool to its ability.
  4. A token that mints other tokens: add token:create, and read attenuation first. A token can only grant what it already holds, and can never pass on token:create.

Team and project scope entries

Alongside abilities, every token carries one required and zero-to-many optional scope entries:

  • scope:team:<uuid>, required. Frozen at mint time; the token can never act outside this team.
  • scope:project:<uuid>, optional, repeatable. If present, the token is restricted to the listed project ids even when the person may see more projects inside the team. A guest's token always carries one.

These are stored in the same array as abilities but are not abilities, and the tokens endpoints report them separately under scopes for that reason. See tenancy and scopes for how they combine with tenant isolation at request time.

How is this guide?

Last updated on

Version

On this page

What changed recentlyEvery release of Zuse Bifrost, with the pages it touched.

For AI agents: llms.txt · llms-full.txt