Repository navigation
pet daemon
The Endo Pet Dæmon (or pet-name daemon) is a persistent background process — a single-node capability OS for one user. It solves the problem of web agency: today, web apps get network access to their origin server by default, and users have no practical control over what those apps can do. The daemon breaks the link between web pages and web servers, confining each app in a hardened JavaScript worker and letting the user grant capabilities by name.
It lives in packages/daemon of the endo monorepo. The CLI (packages/cli) manages its lifecycle: endo start, endo install, endo open, endo eval, etc.
The daemon's user-facing naming layer. Pet names are the "human-meaningful + secure" corner of Zooko's Triangle: personal, familiar, and backed by unguessable cryptographic identifiers.
-
Pet names (lowercase, e.g.
worker,my-app) — user-chosen private names for capabilities. -
Special names (uppercase, e.g.
SELF,HOST,ENDO) — built-in names resolving to fixed system capabilities. - Name paths — arrays of names navigating through naming hubs (directories).
Under the hood, each name resolves to a formula identifier (FormulaNumber:NodeNumber, both 128-hex-digit SHA-512 hashes). The idiom is chat: when user A sends a capability to user B, A refers to it by pet name; on the wire travels the unguessable identifier. B may adopt A's suggested name or pick their own.
The PetNames ocap pattern formalizes this: names are local, not global; there is no central naming authority.
Everything in the daemon is a formula — a persisted JSON record describing how to reconstruct a capability. Formula types include: worker, host, guest, handle, eval, lookup, marshal, readable-blob, pet-store, mail-hub, invitation, peer, promise, resolver, make-bundle, loopback-network, directory, endo, least-authority.
Formulas form a graph persisted to disk. When the daemon restarts, formulas are rehydrated — capabilities survive reboot. Cancellation is hierarchical: cancelling a formula cascades to all dependents.
Host (host.js) — the primary agent with full authority: can create guests, workers, weblets, evaluate code, manage the pet store, send/receive messages. Has special names AGENT, SELF, MAIN, ENDO, NETS, PINS, INFO, MAIL, NONE.
Guest (guest.js) — a confined agent with a handle back to its host. Can use pet names and send messages but cannot create new hosts. This is the capability given to peers and confined programs.
The NONE name resolves to a least-authority formula: a fully inert guest whose every method throws "not allowed." Used as the null capability.
A weblet is "a web page in a box" — a zip file containing a web app. The daemon opens the weblet in a hardened JS worker, spins up a local HTTP server for it, and gives it a CapTP connection back to the daemon. The weblet can request capabilities from the user by name; the user approves or denies.
The HTTP/WebSocket gateway (PR #3100) provides a unified server on 127.0.0.1:8920 — weblets register by hostname (access token) or opt into a dedicated port. Only loopback connections are accepted.
The bootstrap object is the first capability the CLI receives after connecting via CapTP over a Unix domain socket:
-
host()— returns the primaryEndoHostagent -
gateway()— resolves local formula identifiers to their values -
greeter()— peer connection handshake for capability exchange between daemons -
leastAuthority()— returns the inertNONEguest -
terminate()— cancels the daemon -
reviveNetworks()/revivePins()— reincarnates network connections and pinned values after restart
-
CLI ↔ daemon: CapTP over netstrings over a Unix domain socket (
~/.cache/endo/state/private/pid). - Daemon ↔ worker: Same protocol over stdio pipes (fd 3/4 in child process).
- Daemon ↔ peer daemon: OCapN over Noise Protocol (replacing legacy CapTP), with a state machine that resolves crossed connections.
The pet daemon demonstrates a production-grade instantiation of the patterns discussed in this directory:
| Pattern | Daemon instantiation |
|---|---|
| Pet names | User-chosen names for capabilities, not global identities |
| Facet | Host vs Guest — different authority surfaces from the same object |
| CareTaker | Hierarchical cancellation — revoke a formula, its dependents die |
| Least authority |
NONE / least-authority formula as the null capability |
| Bearer tokens | Access tokens for weblet HTTP isolation |
| Capability injection | Workers receive only the endowments they're given at evaluate()
|
| Persistent capabilities | Formula graph survives daemon restart |
For Oros governance, the daemon's pattern of a persistent capability host managing confined agents is directly applicable: steward roles as hosts/guests, governance decisions as formulas in a graph, pet names for human-meaningful authority references.
-
packages/daemon/README.md— daemon overview -
packages/cli/README.md— CLI overview - kriskowal.com/endo — essay on pet daemon design and the web agency problem
- PR #3100 — HTTP/WebSocket gateway
-
packages/daemon/src/daemon.js— bootstrap, formula graph, maker table -
packages/daemon/src/host.js— host agent -
packages/daemon/src/guest.js— guest agent -
packages/daemon/src/pet-store.js— pet name storage -
packages/daemon/src/connection.js— CapTP + netstring framing -
packages/daemon/src/web-server-node.js— weblet gateway
Navigation
- Home
- Governance
- Endo / object capabilities
- Retrospectives and source material