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:
- The app, when a person presses "Create project": their role or group must carry the matching permission.
- The REST API, in the route middleware before the controller runs.
- 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 isinvited andremoved rather than created and deleted, andupdate-roleis its own action.webhook-delivery: a delivery is a record of something that already happened, so it can only be listed, viewed andretry'd.report,dashboardandactivity: read-only, each with the single actionread.
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
| Family | Entities |
|---|---|
| Clients | client |
| Projects | project, project-member |
| Components and environments | component, environment (+ deploy, freeze), repository |
| Project registry | stakeholder, persona, glossary, data-entity, design-reference |
| Planning | epic (+ 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) |
| Build | sprint (+ start, close), time-log (+ approve) |
| Testing | test-suite, test-case (+ approve), test-plan (+ approve), test-run (+ execute, sign-off) |
| Releases and deployments | release (+ freeze, approve, publish, rollback), deployment (+ record, promote) |
| Maintenance | incident (+ command, resolve, publish-update), ticket (+ respond, convert), maintenance-window |
| Knowledge and documents | knowledge, document (+ render, finalise), import |
| Attachments | attachment |
| Comments | comment (+ internal) |
| Reports and dashboards | report:read, dashboard:read |
| Activity log | activity:read |
| AI | ai:use, ai:manage-budgets |
| Teams | team, team-member (view-any, view, invite, remove, update-role) |
| Roles and groups | role, group |
| API tokens | token |
| Webhooks | webhook-endpoint, webhook-delivery (view-any, view, retry) |
| Integrations | integration:manage |
Extras
Five abilities exist for tokens and agents only, outside the team permission catalogue:
| Ability | What it opens |
|---|---|
account:read | GET /v1/me, the caller's notifications and alert destinations. |
account:write | Marking the caller's notifications read and replacing their alert destinations. |
mcp:use | The OAuth scope an MCP client is granted when a person signs in; it stands for their whole catalogue. |
ci:deploy | A pipeline token that records deployments and nothing else. |
ci:test-results | A 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:
| Family | Endpoints |
|---|---|
| Account | GET /v1/me, GET /v1/me/notifications, the two marks, GET /v1/me/alert-destinations and its PUT. |
| Teams | GET /v1/teams, /teams/current, /teams/{team}, create, rename and delete; the roster, one member, the invitations, inviting, re-roling, removing and withdrawing. |
| Roles and groups | List, read, create, update and delete; PUT /v1/groups/{group}/members. |
| API tokens | List, read, mint and revoke. |
| Webhooks | Endpoints: list, read, register, pause, resume, rotate, test, delete. Deliveries: list, read, retry, retry dead. Event samples. |
| Activity log | GET /v1/activity for a project, a client or a project member. |
| Projects | GET /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:
- Read-only tooling: the
:view-anyand:viewabilities for the entities you read, and nothing else. - A pipeline:
ci:deployorci:test-results, confined to one project with ascope:project:entry. - 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.
- 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 ontoken: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
Authentication
Personal access tokens, ability scopes and tenant resolution for the REST API and the MCP server, and what the API will not accept.
Tenancy & Scopes
Every read and write is scoped to one team, scope entries on a token narrow it further to chosen projects, and a guest's token never reaches beyond their invitations.