Skip to main content

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" }
FieldTypeDescription
withstringResource — a path prefix identifying the scope of access
canstringAbility — 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:

  1. The capability resource equals the request resource, OR
  2. The capability resource is a prefix of the request resource

Examples:

Capability withRequest resourceCovered?
w/vendor-recordsw/vendor-recordsYes (exact match)
w/vendor-recordsw/vendor-records/acmeYes (prefix)
w/vendor-recordsw/vendor-records/acme/contactYes (prefix)
w/vendor-recordsw/other-dataNo
w/w/anything/at/allYes (covers entire workspace)
""any resourceYes (wildcard)

Resource Extraction

For each operation, the target resource is derived from the invocation input:

Operation typeResource 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:

  1. The capability ability equals the requested ability, OR
  2. 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:

OperationRequired Ability
covia:read, covia:list, covia:slice, covia:inspectcrud/read
covia:write, covia:appendcrud/write
covia:deletecrud/delete
agent:createagent/create
agent:requestagent/request
agent:messageagent/message
agent:forkagent/fork
grid:run, grid:invokeinvoke
asset:storeasset/store
secret:extractsecret/decrypt
ucan:issueucan/delegate
hitl:requesthitl/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:

  1. Extract the caller's capability vector from the request context
  2. If caps is null, allow (unrestricted)
  3. Extract the target resource from the operation input
  4. Determine the required ability from the operation
  5. Check whether any capability in the vector covers the request
  6. 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:

  1. Agent's LLM requests a tool call
  2. Level 2 adapter resolves the tool to a grid operation
  3. Capability check against the agent's caps
  4. If denied, return error to LLM (operation is not executed)
  5. 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:

  1. Name the denial — identify it as a capability denial
  2. Specify the requirement — operation name, required ability, target resource
  3. List available capabilities — the agent's actual caps in compact format
  4. 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:

FieldDescription
issIssuer DID (who is delegating)
audAudience DID (who receives the delegation)
expExpiry timestamp (Unix seconds, per the JWT NumericDate convention; UCAN v0.10 permits null for a non-expiring token)
attAttenuations — vector of {with, can} capabilities
prfProof 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:

  1. Signature verified against issuer's public key (at every hop of the proof chain)
  2. Expiry checked: exp >= now
  3. Audience DID matched: aud == caller DID
  4. Each capability in att checked for coverage
  5. 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)
  6. 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 with MUST be equal to or a sub-path of the grantor's with
  • The delegate's can MUST be equal to or a sub-ability of the grantor's can

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 of w/

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.