Repository navigation
capability patterns and endo
A capability is an unforgeable reference to an object that confers authority to invoke its methods. OCap discipline rests on two pillars:
- Memory safety + encapsulation — no way to obtain a reference except by creation, construction, or message; no access to internal state without the object's consent.
- Primitive effects only via references — all I/O and ambient authority are passed explicitly, never imported or globally accessible.
See OCap Discipline; Miller's thesis Robust Composition (2006); and the Security PictureBook (Stiegler, 2004).
An intermediary that exposes a restricted subset of a powerful object's interface. E.g., a DepositFacet for a Purse allows deposits but not withdrawals or balance queries. See wiki/Facet.
Wraps a capability such that the grantor can revoke access later. In Endo/Hardened JS: Proxy.revocable(). In E's Walnut: a forwarder that nulls its target on revoke(). The CareTaker pattern is essential for governance — stewards' authority can be revoked when roles change. See wiki/CareTaker.
Like a public-key encryption pair for capabilities: seal creates an inert box; only the matching unsealer can retrieve the original. Used to share identification of a powerful object without sharing authority over it. See wiki/SealerUnsealer and vattr97's src/sealer.ts.
A lightweight token representing the right to retrieve a larger payload later. Analogous to a coat-check ticket. See wiki/ClaimCheck.
A notary attests to facts about an object without granting authority over it; an inspector reads those attestations. Separates certification from access.
Names that are local, personal, and user-chosen rather than global and authoritative. Avoids the confused-deputy problem of global names. See wiki/PetNames.
A token (string, URL, or other datum) that is forgeable in theory but practically unguessable due to high entropy. The token is the capability — whoever holds it exercises the authority.
Examples from the wiki:
-
Pre‑Signed URLs — "The URL is the capability." A signed URL embeds resource identity, expiry, and a cryptographic signature. Possession grants the authorized operation (GET, PUT) until expiry.
⚠️ Bearer semantics — must protect against link leakage. -
Magic Link — A short-lived, single-use URL embedding a cryptographically random token tied to a specific user and purpose (login, password reset). The link is the capability.
⚠️ Bearer semantics — must protect against leakage and reuse. A CareTaker pattern: single-use, time-bound. - API keys, session tokens — ambient in practice: presented at a higher layer (HTTP headers) and scoped to the transport, not to individual objects.
Bearer tokens are a pragmatic concession to environments that lack object-capability memory safety (e.g., HTTP APIs, email links). They sacrifice the "unforgeable by construction" guarantee of ocap references for deployability. The Synergy pattern describes one way to manage them: rights amplification via opaque tokens that only have meaning when presented to the service that issued them.
Hardened JavaScript (aka SES) is what makes the ocap discipline enforceable at runtime. Three primitives do the work:
-
lockdown()— freezes all built-in prototypes, removes ambient authority -
harden()— deep-freezes an object graph so its interfaces are immutable -
Compartment— a sandbox for evaluating code with controlled endowments
The canonical example starts with a simple counter:
const makeCounter = () => {
let count = 0;
return harden({
incr: () => (count += 1),
decr: () => (count -= 1),
});
};
const counter = makeCounter();
counter.incr();Each call creates a new encapsulated count variable and a frozen object with method-only access. There is no class, no this, no prototype mutation — just closure encapsulation + harden().
Because incr and decr are separate references, they can be handed out independently:
entryGuard.use(counter.incr); // can only count up
exitGuard.use(counter.decr); // can only count downThis is the core ocap insight: an object reference is a permission. Give each party only the references it needs.
The same discipline scales to electronic rights. The makeMint pattern (~30 lines) builds on the same closure + harden() technique:
const makeMint = () => {
const ledger = new WeakMap();
const issuer = harden({
makeEmptyPurse: () => mint.makePurse(0),
});
const mint = harden({
makePurse: initialBalance => {
const purse = harden({
getIssuer: () => issuer,
getBalance: () => ledger.get(purse),
deposit: (amount, src) => {
Nat(ledger.get(purse) + Nat(amount));
ledger.set(src, Nat(ledger.get(src) - amount));
ledger.set(purse, ledger.get(purse) + amount);
},
withdraw: amount => {
const newPurse = issuer.makeEmptyPurse();
newPurse.deposit(amount, purse);
return newPurse;
},
});
ledger.set(purse, initialBalance);
return purse;
},
});
return mint;
};The progression is:
makeCounter → makeMint (mint + purse + issuer) → ERTP (brands, payments, deposit facets)
The mint creates purses, purses hold balances, deposit/withdraw move value, and the issuer is a separate facet for creating empty purses. All of ERTP's security properties — payments consumed on deposit, no forgery, no double-spending — emerge naturally from the ocap discipline: harden() prevents interface tampering, closure encapsulation protects balances, and reference-based access replaces identity-based authorization.
This is covered in 8 min in The Mint Pattern (starting at 25:25).
The mint pattern introduces a key ocap design distinction:
| Category | Examples | Authority |
|---|---|---|
| Closely held | Purse, Mint, Unsealer | Full: withdraw, mint, unseal |
| Widely shared | DepositFacet, Brand, Sealed token | Narrow: deposit only, inert |
A purse is closely held — only its owner can withdraw. But its DepositFacet is widely shared — anyone can deposit into it. This asymmetry enables safe cooperation: you can receive payments without risking your balance.
Endo is a distributed secure computing platform that implements object-capability security in JavaScript. Built on TC39 standards.
Three primitives enforce the ocap discipline at runtime:
-
lockdown()— freezes all built-in prototypes, removes ambient authority (e.g.,Date.now()is available but the constructor is frozen; no globalfetch, norequire). -
harden()— deep-freezes an object graph so its interfaces are immutable and cannot be tampered with. -
Compartment— a sandbox for evaluating code with a controlled set of endowments. Each compartment has its own global scope and can only reach what is explicitly injected.
import 'ses';
lockdown();
const c = new Compartment({ console, request: makeSafeRequest() });
c.evaluate(untrustedCode);A vat is a unit of synchrony: one event loop, one message queue, one heap. Synchronous calls only work within a vat; cross-vat communication uses eventual send (E()). Vats may live on different machines or blockchains.
Objects shared across vats are remotables, created with Far() or makeExo(). They get automatic serialization (marshaling) so they can be passed by reference via E().
const result = E(counter).incr(); // returns a promiseE(obj).method(args) sends a message asynchronously to obj, which may be local or in another vat. Messages are delivered in FIFO order per-object. On a promise, .then() is pipelined — the message is forwarded when the promise resolves.
The OCapN protocol extends capabilities over the network. It provides secure, promise-pipelined RPC between vats on different machines, using CapTP as the transport.
| Capability | Governance application |
|---|---|
| Unforgeable references | Steward roles are just references — no certificates, no keys, no PKI |
| Composable delegation | Lead Steward issues domain steward capabilities; stewards delegate sub-roles |
| Revocation | CareTaker pattern: revoke a steward's capability when they leave the role |
| Attenuation | Facet pattern: issue a "read-only governance log" facet to auditors |
| No ambient authority | Every governance action requires explicit presentation of a capability |
| Substrate independence | Same capabilities work locally, over a network, or on a blockchain |
Navigation
- Home
- Governance
- Endo / object capabilities
- Retrospectives and source material