COG-13: Agent Capabilities
Status: Draft (Work in Progress)
Version: 0.1
Created: 2026-04-12
Authors: Mike Anderson
:::caution Work in Progress This specification is under active development. Structure and details may change significantly based on implementation experience and community feedback. :::
This standard specifies the capability model for agent authorisation on the Covia Grid — how fine-grained access to operations and resources is granted to agents, attenuated through delegation, disclosed in agent context, and enforced at runtime.
This COG supersedes the "Capability enforcement" future direction in COG-11: Agent Lifecycle by providing the complete semantic model and enforcement architecture.
Purpose
Authentication (COG-10) establishes who a caller is. Capabilities establish what they may do:
- Least privilege — agents receive only the permissions their role requires
- Transparent boundaries — agents are told what they can do, preventing trial-and-error discovery
- Structural denial — denied operations return actionable errors, not ambiguous failures
- Delegable authority — users can delegate scoped authority to agents or other users via UCAN tokens
- Attenuation — delegated capabilities can only narrow, never widen, the grantor's authority
Terminology
See COG-1: Architecture for Grid terminology and COG-11: Agent Lifecycle for agent state.
A Capability is a {with, can} pair granting an ability on a resource.
An Attenuation is a vector of capabilities assigned to an agent, restricting its operations to those covered by at least one capability in the vector.
A UCAN (User Controlled Authorisation Network) is a signed token encoding a delegation of capabilities from an issuer to an audience.
Capability Structure
A capability is a map with two required fields:
{ "with": "w/decisions/", "can": "crud/write" }
| Field | Type | Description |
|---|---|---|
with | string | Resource — a path prefix identifying the scope of access |
can | string | Ability — a slash-delimited permission in the ability hierarchy |
An agent's capabilities are expressed as a vector of capability maps in the caps field of the agent record (COG-11):
"caps": [
{ "with": "w/vendor-records/", "can": "crud/read" },
{ "with": "w/enrichments/", "can": "crud" },
{ "with": "g/helper", "can": "agent/message" }
]
Null vs Empty
- Null caps (field absent or
null): unrestricted access — no capability checking is performed - Empty caps (
[]): deny-all — every operation is denied
This distinction is critical. A newly created agent with no caps field has full access. An agent with caps: [] can do nothing.
Resource Matching
The with field is a path prefix. A capability's resource covers a request's target resource if:
- The capability resource equals the request resource, OR
- The capability resource is a prefix of the request resource
Examples:
Capability with | Request resource | Covered? |
|---|---|---|
w/vendor-records | w/vendor-records | Yes (exact match) |
w/vendor-records | w/vendor-records/acme | Yes (prefix) |
w/vendor-records | w/vendor-records/acme/contact | Yes (prefix) |
w/vendor-records | w/other-data | No |
w/ | w/anything/at/all | Yes (covers entire workspace) |
"" | any resource | Yes (wildcard) |
Resource Extraction
For each operation, the target resource is derived from the invocation input:
| Operation type | Resource derivation |
|---|---|
Workspace operations (covia:read, covia:write, etc.) | The path parameter |
Agent operations (agent:request, agent:create, etc.) | g/<agentId> from the agentId parameter |
Grid operations (grid:run, grid:invoke) | No resource-specific check |
Operations without a derivable resource are checked only for ability coverage, not resource scope.
Cross-User Resources
Resources may include a full DID URL for cross-user access:
{ "with": "did:key:zAlice.../w/shared-data", "can": "crud/read" }
This enables capability delegation across user boundaries — see UCAN Delegation.
Ability Hierarchy
Abilities are slash-delimited strings forming a hierarchy. A capability's ability covers a requested ability if:
- The capability ability equals the requested ability, OR
- The capability ability is a prefix of the requested ability
The wildcard ability "*" covers any requested ability.
Standard Abilities
crud (any CRUD operation)
├── crud/read (read, list, slice, inspect)
├── crud/write (write, append)
└── crud/delete (delete)
agent (any agent operation)
├── agent/create
├── agent/request
├── agent/message
└── agent/fork
invoke (operation execution)
asset (asset operations)
└── asset/store
secret (credential access)
└── secret/decrypt
ucan (token delegation)
├── ucan/delegate
└── ucan/revoke
venue (venue actions on the caller's behalf)
└── venue/relay (relay a cross-venue request as the venue itself)
hitl (human-in-the-loop requests)
└── hitl/request (deliver a HITL request into a user's h/ inbox)
grant (meta: rights to issue grants — see COG-17)
└── grant/<ability> (the right to grant <ability>; composes recursively)
A venue/relay capability is granted to a venue (aud = the venue's DID, iss = the caller): it instructs and authorises that venue to make a cross-venue hop authenticated as itself, exercising the caller's delegation. The instruction is only honoured when its issuer is the authenticated caller.
The grant family is a meta-family: for any ability X, grant/X is the right to have a grant of X minted at a granting surface, distinct from the right to exercise X (grant/crud/read does not cover crud/read, and vice versa). Granting semantics — grantable authority and issuance — are specified in COG-17: Capability Granting; chain verification remains grant-agnostic.
Operation-to-Ability Mapping
Each operation maps to a required ability:
| Operation | Required Ability |
|---|---|
covia:read, covia:list, covia:slice, covia:inspect | crud/read |
covia:write, covia:append | crud/write |
covia:delete | crud/delete |
agent:create | agent/create |
agent:request | agent/request |
agent:message | agent/message |
agent:fork | agent/fork |
grid:run, grid:invoke | invoke |
asset:store | asset/store |
secret:extract | secret/decrypt |
ucan:issue | ucan/delegate |
hitl:request | hitl/request (against the target user's h/ — see COG-16) |
A capability with ability crud covers crud/read, crud/write, and crud/delete. A capability with ability crud/read does NOT cover crud/write.
Enforcement
Enforcement Point
Capability checking occurs before an operation is dispatched to its adapter. The enforcement point is the job invocation layer:
- Extract the caller's capability vector from the request context
- If caps is null, allow (unrestricted)
- Extract the target resource from the operation input
- Determine the required ability from the operation
- Check whether any capability in the vector covers the request
- If no capability covers the request, deny with a structured error
Matching Algorithm
For a request with resource R and ability A, check each capability C in the agent's caps vector:
ALLOW if any C where:
C.with is a prefix of R (or C.with == "")
AND
C.can is a prefix of A (or C.can == "*")
DENY otherwise
First matching capability allows the operation. Order does not matter.
Agent Tool Calls
In the agent architecture (COG-11), capability checking applies at the Level 2 (domain logic) tool dispatch point:
- Agent's LLM requests a tool call
- Level 2 adapter resolves the tool to a grid operation
- Capability check against the agent's caps
- If denied, return error to LLM (operation is not executed)
- If allowed, invoke the operation
Level 3 (LLM call) is NOT capability-gated — the LLM invocation itself is always permitted. Only the agent's tool calls are restricted.
Disclosure
Capabilities MUST be disclosed to agents in their system prompt so the LLM knows its boundaries. The disclosure section is formatted as:
## Your capabilities (caps)
- crud/write on w/decisions/
- crud/read on w/
- agent/message on g/Alice
Tool calls outside these capabilities will fail with a "Capability denied" error.
Retrying the same call does not help — the denial is structural.
Disclosure MUST be refreshed every turn from the current agent configuration. Updates to an agent's caps take effect immediately without requiring a restart.
Denial Messages
When an operation is denied, the error message MUST:
- Name the denial — identify it as a capability denial
- Specify the requirement — operation name, required ability, target resource
- List available capabilities — the agent's actual caps in compact format
- Guide behaviour — state that retrying will not succeed and the denial is structural
Example:
Capability denied: v/ops/covia/write requires crud/write on w/audits/INV-123.
Your capabilities are: crud on w/decisions/, crud/read on w/.
Retrying the same call will not succeed — the denial is structural.
This design prevents LLM agents from looping on impossible operations by making boundaries actionable information.
UCAN Delegation
Capabilities are delegated via UCAN (User Controlled Authorisation Network) tokens — signed JWTs encoding a chain of authority from the resource owner to the delegate.
Token Structure
A UCAN token contains:
| Field | Description |
|---|---|
iss | Issuer DID (who is delegating) |
aud | Audience DID (who receives the delegation) |
exp | Expiry timestamp (Unix seconds, per the JWT NumericDate convention; UCAN v0.10 permits null for a non-expiring token) |
att | Attenuations — vector of {with, can} capabilities |
prf | Proof chain — vector of parent UCAN tokens |
Issuance
Tokens are issued via the ucan:issue operation:
{
"operation": "v/ops/ucan/issue",
"input": {
"aud": "did:key:z6Mk...",
"exp": 1795000000,
"att": [
{ "with": "w/shared-data/", "can": "crud/read" }
]
}
}
The input field names deliberately match the UCAN claim names (aud, att, exp, and optionally prf for granting held authority) — see COG-17: Capability Granting for the full input schema and grantable-authority rules.
The venue signs the token with its own keypair; the issuer is the venue DID. Attenuations MUST lie within the caller's grantable authority: the caller's own namespace (ownership carries implicit granting rights), or a resource over which the caller presents a grant/… proof chain (COG-17). Access to a resource does not confer the right to grant it — in particular, agent sub-principals acting within an owner's namespace hold no granting authority over it and cannot issue grants.
ucan:issue is a convenience for callers without their own signing key. A resource owner holding a did:key keypair MAY equally sign grants over their own namespace directly (a self-sovereign grant, iss = the owner) — no venue involvement, verifiable by any venue.
Verification
On each request, UCAN tokens are verified:
- Signature verified against issuer's public key (at every hop of the proof chain)
- Expiry checked:
exp >= now - Audience DID matched:
aud == caller DID - Each capability in
attchecked for coverage - If the proof chain is non-empty, each parent UCAN verified recursively, and each hop's capability MUST be covered by its parent (per-hop attenuation, fail-closed at the capability)
- Root authority: the chain root's issuer MUST be entitled to root a grant over the resource — the DID owning the resource (self-sovereign), or a venue the verifier's root-authority policy accepts for attestation over that resource (COG-15; by default, the venue hosting the resource). Any other root is refused
Attenuation Rule
Delegated capabilities can only narrow the grantor's authority:
- The delegate's
withMUST be equal to or a sub-path of the grantor'swith - The delegate's
canMUST be equal to or a sub-ability of the grantor'scan
For example, a grantor with {with: "w/", can: "crud"} can delegate:
{with: "w/reports/", can: "crud/read"}— narrower on both resource and ability{with: "w/reports/", can: "crud"}— narrower on resource, same ability
But cannot delegate:
{with: "s/secrets/", can: "crud/read"}— different resource, not a sub-path ofw/
Chain delegation of held abilities is transitive and visible: a holder may sign a narrowed onward delegation, and the proof chain names every delegator — re-delegation is audited, not blocked. Minting new chain-free authority is different: a granting surface requires the granting right grant/<ability> before producing a token on a caller's instruction (resource owners hold all granting rights implicitly). The granting model is specified in COG-17: Capability Granting.
Agent Capability Models
User-Scoped (Current)
The agent has no independent identity. It acts under its owner's DID with attenuated capabilities:
- Venue issues a scoped capability set at agent creation
- Caps are stored in the agent record alongside config
- Tool calls carry the owner's DID with the agent's restricted capability set
- The venue enforces capability checks on every tool invocation
Independent (Planned)
The agent has its own Ed25519 keypair and DID:
- Agent can receive delegations from multiple users
- Agent signs its own UCANs for sub-delegation to child agents
- Tool calls carry the agent's DID and proof chain
- Full UCAN verification with delegation chain walking
Security Considerations
Principle of Least Privilege
Agents SHOULD be configured with the minimum capabilities required for their role. The AP demo illustrates this:
- Alice (scanner): no workspace access, structured output only
- Bob (enricher): read vendor records, write enrichments
- Carol (approver): read all workspace, write decisions only
Empty Caps as Sandbox
Setting caps: [] creates a fully sandboxed agent that cannot invoke any tools. Combined with defaultTools: false, this produces a pure reasoning agent with no side effects.
Capability Escalation
Agents with agent/create capability can create child agents. Venues MUST ensure that child agents cannot be created with broader capabilities than their parent. The attenuation rule applies transitively.
Disclosure Accuracy
The capability disclosure in the system prompt MUST accurately reflect the enforced capabilities. Discrepancies between disclosed and enforced capabilities would cause agents to attempt operations they believe are permitted but that will be denied.
Examples
Read-Only Analyst
"caps": [
{ "with": "w/", "can": "crud/read" }
]
Can read any workspace path. Cannot write, delete, or invoke agent operations.
Scoped Worker
"caps": [
{ "with": "w/vendor-records/", "can": "crud/read" },
{ "with": "w/enrichments/", "can": "crud" },
{ "with": "g/helper", "can": "agent/message" }
]
Can read vendor records, perform full CRUD on enrichments, and send messages to the "helper" agent.
Manager with Delegation
"caps": [
{ "with": "w/", "can": "crud" },
{ "with": "g/", "can": "agent" }
]
Full workspace access and full agent management. Can create, request, message, and fork any agent.
Related Specifications
- COG-1: Architecture — Overall Grid architecture
- COG-10: Authentication — Authentication (identity establishment)
- COG-11: Agent Lifecycle — Agent state, the
capsfield, and the run loop - COG-12: Orchestrations — Orchestration steps subject to capability enforcement