The Core Insight

ATProto is a stateful, universally addressed data protocol. Records exist. They persist. They outlive any particular action taken on them. This is not incidental — it is the foundational property that makes ATProto what it is.

Capability Trees is built around this property. A delegation is not a token you present at invocation time. It is a record that exists on its issuer's PDS right now, or it does not. Verification resolves live records and asks: does this chain currently exist? The answer is in the state of the world at the moment of asking. This is a different trust model than token-based capability systems, and the difference matters.


The Problem

Traditional object capability systems assume a controlled runtime. Possession of an unforgeable reference is sufficient authorization — if you hold it, you can use it. This works in closed systems where the runtime mediates all access.

In an open decentralized protocol like ATProto, this assumption breaks. Anyone can read records, build clients, and attempt to use references. The runtime cannot be trusted to mediate all access.

Modern distributed capability systems address this with audience restriction: a capability is cryptographically bound to its intended recipient and requires a signature from that recipient at invocation time. Possession alone is insufficient; you must prove you are the intended audience.

These systems are invocation-oriented — a capability token is presented to perform an action. ATProto is different in kind. It is a stateful, universally addressed data protocol where records persist and outlive any particular invocation. Capability Trees is built for this model. Authority is not carried in a token presented at invocation time. It exists in the state of the world — in records on PDSes, right now — and is verified by resolving that state directly. Capability Trees adds one property this model makes uniquely tractable: sovereign revocation without a revocation list, grounded in ATProto's existing deletion semantics.


Permission Sovereignty

ATProto already provides data sovereignty. Your data lives on your PDS. You control it, you can export it, you can migrate it. That problem is solved.

What ACLs cannot provide is permission sovereignty — the ability to control what others are authorized to do with your data, selectively and unilaterally, even against a malicious application. Under an ACL system, permissions are defined and enforced by the administrator. The application is the enforcement point. A malicious application can redefine or ignore the permission structure entirely. Your only recourse is exit.

Permission sovereignty means you hold the levers over your own authorization relationships independently of any application or administrator. Revoking a capability is an act on your PDS that no application can prevent or override. The application defines what permissions mean. The protocol enforces whether they are honored. ACLs leave enforcement to the application, making governance structures fragile and permission sovereignty impossible. Capability Trees moves enforcement to the protocol, making permission sovereignty real even against malicious applications.

This is not a minor implementation difference. It is a different theory of where enforcement lives — and where enforcement lives determines whose interests it serves.


The Stack In Brief

Capability Trees is built in three layers, each necessary for a different reason.

The stateful layer is the foundation. Authority exists as records on PDSes — live, auditable, and revocable by deletion. This is what makes permission sovereignty real: enforcement lives in the protocol, not in any application that could be subverted or replaced.

The verification service sits on top of the stateful layer as a convenience and optimization layer. Resolving a delegation chain requires fetching records from multiple PDSes in parallel — the verifier does this work once and caches the result, and tracks active delegations so that revocations propagate immediately. It is optional: any entity can resolve a chain directly against the PDSes, and the verifier introduces no new trust requirements.

UCANs sit on top of the verification service as a snapshot layer. Some use cases — high-frequency operations, offline work — cannot re-verify from scratch on every action. A UCAN is a snapshot of a verified chain, signed by the verifier, bound to a specific recipient, and valid for a bounded window. It carries verified state across contexts where live resolution is impractical, without replacing the stateful layer as the source of truth.

Each layer does one thing the layer below it cannot. Together they cover the full range of access patterns an open decentralized protocol demands.


The Stateful Layer

Bilateral Delegations

Every delegation in Capability Trees is bilateral. A delegation requires two records to be active simultaneously: a give record on the delegator's PDS and a take record on the delegatee's PDS. The give record alone is an invitation. The take record is a request. When both are present, the capability is active. When either is absent, it is not. Either party can void their side independently at any time, without the other party's cooperation or knowledge.

If the delegatee deletes their side, the delegator's record becomes an open invitation again. If the delegator deletes their side, the delegatee's record becomes a standing request. Deletion is not erasure — the surviving record retains its meaning and the relationship is recoverable by the same party re-issuing their side, so long as the other side remains.

This makes every authorization relationship a mutual agreement — a social contract with cryptographic teeth on both sides.

Mismatched gives and takes records do not error — they simply do not form a valid pair. A gives record without a matching takes record is an open invitation. A takes record without a matching gives record is a standing request. Neither state is invalid; neither constitutes an active capability.

Scope attenuation:

The delegator's record may be of broader scope than the delegatee's acceptance. You do not have to accept the full extent of what was offered — only what you need.

Fractal accountability:

Each party in the chain is accountable upward to whoever granted them access and authoritative downward over whoever they delegated to. Governance happens as close to the terrain as possible.

Record Types and Resource Specification

There are two record types: gives and takes. Every record specifies the resource it pertains to, though only the root record's resource specification is strictly required for the chain to function. Specifying the resource at every link makes the chain more auditable and tamper-evident — an inspector can confirm internal consistency without having to trust the presenter's assembly of the chain.

The root record anchors the resource the chain is protecting.

Revocation

A delegation can be revoked anywhere in the chain by the deletion of any of its comprising records. The issuer deletes their delegation record. The PDS returns a 404. The chain breaks immediately, without coordination, without a revocation list, without notifying downstream delegatees. Absence of the record is the answer.


The Verification Service

The verification service is a convenience and optimization layer built on top of the stateful core. PDSes remain the sources of truth. A verification result cannot grant access that does not exist in the underlying records — it can only attest to what was observed when the chain was resolved.

The verifier is optional. Any entity can resolve a chain directly against the PDSes without using a verifier at all, and any entity that wants the convenience layer can run their own. If the verifier is unreachable, the fallback is always to check the PDSes directly.

The Verification Process

To verify a capability, the presenter submits a list of AT URIs claiming to constitute a valid chain. Each URI is resolved in parallel from its authoritative PDS, confirming the existence and structural validity of each record and that every bilateral link is complete — both the gives and takes records present and valid. Because links are resolved in parallel, verification latency is bounded by the slowest single PDS in the chain — not by chain depth.

The verification request itself is the audience proof. The requester signs the request with their private key. The verifier finds the intended recipient DID at the terminal link and checks it against the DID document of whoever signed the request. If they match, the requester has proven they are the intended audience without presenting anything beyond an authenticated request. This is the same inter-service authentication ATProto already uses throughout — Capability Trees inherits it as ambient infrastructure.

The verifier listens to the firehose and maintains a cache of capabability tree records. A verification request first returns optimistically based on the cache, and then it checks all relevant PDSes live in parallel. Following that check, it additionally returns one of three results:

  • Green light — all links resolved and valid; both sides of every bilateral link are present; the chain currently exists.

  • Abort — a link returned a definitive 404; the chain is broken; revocation is authoritative.

  • Unresolvable — one or more PDSes did not respond; the state is ambiguous. Applications handle this by transparently surfacing the ambiguity to the user: the operation cannot be performed right now, and why.

The distinction between abort and unresolvable is load-bearing. A 404 on a delegation record is authoritative — the authorization no longer exists. A timeout is ambiguity about state. Collapsing these into the same signal would force clients to treat a network hiccup as a revocation, undermining the entire value of the stateful model.

For one-off operations, the application stages the operation optimistically and waits for the green light before committing. The user sees a fast response immediately. Data integrity waits on the authoritative result in the background. On an unresolvable result, the operation is bounced and the user is told why — it is a temporary infrastructure issue, not a rejection.

This is standard optimistic concurrency. No exotic error handling required.


UCANs as Delegation Snapshots

If requested, the verification service may return a UCAN in the body of the green light. The lifetime of the UCAN must be specified so the UCAN will always eventually expire on its own.

UCANs may be issued by the verifier as attestations of chain validity at a moment in time, and revoked by the verifier via the denylist notification mechanism. The UCAN lifecycle — issuance, active monitoring, and revocation — is entirely owned by the verifier.

Two Birds, One Stone

UCANs can be used for both high-frequency and offline use cases. The application requests a UCAN attestation from the verification service upfront. The verifier resolves the chain online, confirms both sides of every bilateral link, and issues a UCAN attesting to the validity of that chain for the requesting DID, with an expiry bounding the staleness window. To use the UCAN, the holder proves they control the private key of the audience DID by signing a challenge with it. Possession of the UCAN alone is insufficient — you must also hold the private key of the DID it was issued to.

High-frequency work: Request a UCAN at the start of the work session. Pay the verification cost once. Use the UCAN locally through the window. Refresh when it expires. Network bandwidth is not consumed on every operation.

Offline operation: Request a UCAN with a longer expiry before going offline. Use it while disconnected. The staleness tradeoff is explicit and chosen.

Expiry window is the only variable the application controls. If the verifier made a mistake — a conservative revocation due to a temporarily unreachable PDS — the holder simply requests a fresh UCAN.

Direct PDS Subscription

For active UCANs, the verifier subscribes directly to the relevant PDSes for each UCAN's lifetime. These direct subscriptions provide the low-latency signal needed for prompt denylist notification. A single PDS subscription serves as the source for all UCAN listeners associated with records on that PDS — subscriptions and listeners are maintained as separate layers, so one subscription can notify multiple UCAN listeners without redundant network connections.

When a deletion event arrives, the verifier identifies the affected UCAN listeners, pushes denylist entries to the relevant resources, and retries for any unreachable resources until the affected UCANs expire.

Revocation via Denylist Notification

When a chain breaks, the verifier pushes a denylist entry to the relevant resource. The resource denies any UCAN on the denylist on sight, regardless of expiry.

If the resource is unreachable at the moment of revocation, the verifier retries until the affected UCAN expires. An attacker cannot exploit the staleness window by making a resource temporarily unreachable — the verifier persists in pushing the denylist entry until it is no longer needed.


Ecosystem Convergence

Capability Trees is ATProto-native, but its relevance is broader than ATProto alone.

UCAN encodes delegations in DAG-CBOR. ATProto records are DAG-CBOR. The UCAN delegation specification — co-authored by Brooklyn Zelenka and Daniel Holmgren — uses IPLD schemas, the same content-addressing substrate ATProto is built on. There is no serialization boundary between the stateful layer and the invocation layer. The verifier resolves DAG-CBOR delegation records, walks a DAG-CBOR chain, and produces a DAG-CBOR UCAN. The encoding is consistent throughout.

This is not coincidence. It is convergence — a set of people working on adjacent problems in decentralized systems arriving at shared primitives. DAG-CBOR as a shared data format. Content addressing as a shared integrity model. Audience-bound delegation as a shared authorization primitive. ATProto as the stateful substrate that gives the whole stack a home.

Capability Trees sits at this convergence point. It is implementable once, shared across every project that uses it, and legible to anything else in the ecosystem that speaks the same language.


Open Questions

The full picture of permissioned spaces requires more than Capability Trees alone. The space boundary question — how membership is defined, how the cryptographic boundary of a space stays current with its membership, how a space's collective signing key works without concentrating that key in any individual — is the most significant open question. It sits below this layer, in the infrastructure that Capability Trees builds on top of.

Work is actively underway. Nick Gerakines' metadata-only CAR proposal addresses the network boundary. The collective cryptography question — a skip ratchet based construction for epoch-based collective signing keys, where membership change is the epoch boundary — is the next piece of work. Brooklyn Zelenka's skip ratchet is the relevant prior art.

Above this layer, the governance question remains: how does a collective make binding decisions, and how is the legitimacy of those decisions made legible and enforceable at the protocol level? That is the virtualized administrator — a future document.

We are working through these questions. Please bear with us.


Properties

  • No ACLs at any layer

  • No revocation lists in the stateful layer

  • No central administrator

  • No coordination required for revocation

  • Bilateral delegations — every authorization relationship requires mutual agreement, voidable from either side

  • Mismatched gives and takes records do not error — they simply do not form a valid pair

  • Every record specifies the resource; only the root is strictly required for chain validity

  • Presenter-submitted chains — the presenter assembles the chain; the verifier confirms it

  • Revocation effective within a single network round trip to the issuer's PDS

  • Denylist notification for active UCANs — revocation propagates immediately to resources, with retry until expiry for unreachable resources

  • Verification latency bounded by slowest PDS, not chain depth

  • Two verification modes: online stateful for one-off operations, UCAN attestation for sustained or offline work

  • Verification service as convenience and optimization layer — PDSes remain sources of truth

  • Verifier written once, shared by every project — ecosystem absorbs implementation cost once

  • Delegation chains fully legible and auditable

  • Fractal accountability: authority flows downward, accountability flows upward

  • Permission sovereignty: enforcement lives in the protocol, not the application

  • Ecosystem convergence: DAG-CBOR throughout, composable with UCAN and IPLD tooling