Capabilities
Covia uses capabilities to decide what an authenticated caller — a user, an agent, or another venue — is allowed to do. A capability is a signed grant that says "this holder may perform this ability on this resource". Covia's model follows UCAN (User-Controlled Authorization Networks): capabilities are carried as signed tokens, can be attenuated (narrowed) when delegated, and are checked at the point of use.
Authentication answers who you are (see the operator auth guide); capabilities answer what you may do.
The shape of a capability
A capability is a {with, can} pair:
with— the resource, as a path or URI: a lattice path likeo/shared/orw/reports/, or a typed resource such asfile://workspace/ordlfs://notes/.can— the ability:crud/read,crud/write,crud/delete, or*for all.
{ "with": "o/shared/", "can": "crud/read" }
A grant covers a request when its resource is a prefix of the target and its ability includes the required one. Reads require crud/read, writes/appends/mkdir require crud/write, deletes require crud/delete.
Two ways capabilities are applied
1. Agent caps
An agent's config can carry a caps array. Once set, every operation the agent attempts is checked against it — the agent cannot exceed its grant, even via tool calls:
"caps": [
{ "with": "w/vendor-records/", "can": "crud/read" },
{ "with": "w/enrichments/", "can": "crud" },
{ "with": "file://workspace/", "can": "crud/write" }
]
The agent's capabilities are disclosed in its system prompt so the model knows its limits up front. A denied call returns a structural error — it names the required ability and resource and lists what the agent holds, and signals that retrying won't help — so the agent adapts instead of looping. (An agent with no caps is unrestricted within its owner's namespace.)
2. UCAN tokens on a request
A caller can present a UCAN as a bearer token. The venue verifies it at ingress and treats the proven capabilities as authority for that request:
Authorization: Bearer <ucan-jwt>
This works on both the REST API and the MCP endpoint. The token's issuer (iss) is taken as the caller DID, and the token is stashed as a capability proof for the operation. Requests may also carry proofs explicitly via the ucans field of the invoke envelope.
This is what enables cross-user access: if Alice issues Bob a UCAN granting {with: "o/shared/", can: "crud/read"}, Bob can present it to read under Alice's o/shared/ namespace — access he wouldn't otherwise have. The venue trusts the verified proof, not Bob's bare identity.
Issuing a UCAN
The ucan:issue operation mints a venue-signed UCAN delegating capabilities to an audience:
{
"operation": "v/ops/ucan/issue",
"input": {
"aud": "did:key:z6MkBob...",
"att": [
{ "with": "o/shared/", "can": "crud/read" }
],
"exp": 1767225600
}
}
| Field | Meaning |
|---|---|
aud | Audience DID — who receives the capability |
att | Attenuations — the {with, can} grants being delegated |
exp | Expiry, in unix seconds |
The result is a JWT the audience presents as a bearer token. Because UCANs attenuate, the audience can in turn delegate a narrower subset onward, but never more than it holds.
Capability-gated adapters
Capability checks apply across the venue. In particular, the file: and dlfs: adapters are gated on typed resources (file://<root>/<path>, dlfs://<drive>/<path>), so a grant can scope filesystem access down to a single root or path.
Related
- Operator: Authentication — how callers are identified
- Creating Agents — setting an agent's
caps - File Adapter — capability-gated filesystem access
- COG-013: Agent Capabilities — the protocol specification