COG-13: Agent Capabilities
Status: Draft (Work in Progress)
Version: 0.1
Created: 2026-04-12
Authors: Mike Anderson
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
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:request, agent:message, agent:fork | agent/* |
grid:run, grid:invoke | invoke |
asset:store | asset/store |
secret:extract | secret/decrypt |
ucan:issue | ucan/delegate |
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 |
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": "ucan:issue",
"input": {
"audience": "did:key:z6Mk...",
"expiry": 1718000000000,
"attenuations": [
{ "with": "w/shared-data/", "can": "crud/read" }
]
}
}
The venue signs the token with its own keypair. The issuer is the venue DID (Phase C1). Attenuations MUST be within the caller's own namespace.
Verification
On each request, UCAN tokens are verified:
- Signature verified against issuer's public key
- Expiry checked:
exp >= now - Audience DID matched:
aud == caller DID - Each capability in
attchecked for coverage - If proof chain is non-empty, each parent UCAN verified recursively
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/
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