Endo: object capabilities and hardened JavaScript for plugin systems
Endo is a distributed secure JavaScript sandbox, based on SES
At a glance
- What is it?
- Endo is a framework for JavaScript plugin systems that resists supply chain attack, built on SES lockdown and compartments, an eventual-send abstraction for remote objects, and a petname daemon that gives capabilities human-readable names.
- Who is it for?
- Endo suits a team building a plugin platform, a web extension, or a smart contract system where third-party code must run with limited authority and where prototype pollution is a live risk. It is a poor fit for an ordinary application with no untrusted code, since lockdown and compartments cost real work to adopt and buy nothing without a hostile dependency.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 8 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Supply chain attack resistance as the organising idea
Endo is a framework for powerful JavaScript plugin systems and supply chain attack resistance, and it includes tools for confinement, communication and concurrency. The threat model is specific and worth restating because it determines whether the framework is relevant to you: hacks that enter through upgrades to third-party dependencies.
The response is a combination of two ideas. The Principle of Least Authority says a software component should only have access to the data and resources that enable it to do its legitimate work. The Object-capability Model, usually shortened to OCaps, gives programmers a place to reason by construction about how permission flows through a program, using mechanisms like encapsulation that are already well understood.
The list of who relies on this is short and specific: Agoric and MetaMask rely on Hardened JavaScript and the SES shim as part of systems that sandbox third-party plugins or smart contracts and mitigate supply chain attacks for production web applications, web extensions and build systems.
That list is the honest answer to the question of who should use Endo. If you are shipping a web extension that loads third-party code, or a blockchain runtime executing smart contracts, or a plugin platform where users install code written by strangers, the supply chain threat is your problem and this framework addresses it. If you are building an internal dashboard, the entire premise does not apply to you.
Lockdown, harden, compartment
Hardened JavaScript introduces three components to the base language, and understanding the difference between them is what makes the rest of Endo legible.
Lockdown is the global operation. It freezes the shared intrinsics, the subset of the JavaScript intrinsics like the Array and Object prototypes, so they are safe to share between programs running in compartments. Once the realm is locked down, the standard objects can no longer be tampered with by anyone in the process.
Harden is what you apply to your own objects. After lockdown, programs use harden to make other objects safe to share between compartments.
A compartment is the isolation unit. Code inside a compartment sees a curated set of globals and cannot reach outside except through what it has been handed.
From those three, the guarantees follow. Hardened objects can represent capabilities, meaning that holding a reference to an object means you can use that object. JavaScript itself guarantees that capabilities cannot be forged, because a useful reference cannot be obtained by guessing its address. The language also enforces structures like closures and WeakMap that can guard capabilities. The only way to obtain a capability is to have received it as an argument, a return value, a global, or a module of the surrounding compartment. And once hardened, an object and its methods cannot be altered.
That is the foundation of the object-capability security paradigm, and the key property for plugin systems is the last one. A hardened object handed to a plugin cannot be monkey-patched by that plugin, which is exactly the prototype pollution and dependency attack class the framework is aimed at.
From in-process references to references over a network
Endo then stretches the object-capability model across process and network boundaries, and this is where the design changes character.
The reasoning is that once a reference crosses a network, the guarantee can no longer rest on JavaScript's memory safety, so it rests on cryptography instead. A suitably large, signed, cryptographically random number, reachable over a network over an encrypted connection, may safely designate a capability. That is a capability transport protocol, and Endo names OCapN as the one it is working toward, with CapTP as a concrete transport that exists today.
Eventual Send is the portable abstraction over those transports. It gives a safe, transport-agnostic way of pipelining messages to remote procedures, so the programmer does not have to build a bespoke protocol over message ports or byte streams. CapTP, in Endo's description, frees the programmer from needing to create bespoke communication protocols at all.
The performance framing is separate and worth distinguishing. For distributed systems, Endo stretches object-oriented programming over networks using asynchronous message passing to remote objects. For workers and networks, the same Eventual Send and capability transport protocols stretch asynchronous method invocation across processes and networks, and the claim there is about ergonomics of message passing between components in separate workers rather than about a new protocol.
The Rust side of the repository points at the same direction. The Cargo workspace has a single member, rust/ocapn_noise, which is the noise protocol implementation for OCapN, so the network transport is being written in Rust while the object model stays in JavaScript.
LavaMoat sits on top and turns least authority into policy files
One piece of the documentation deserves separate attention because it is the part most teams would actually adopt first.
The problem it addresses is that most JavaScript libraries receive powerful capabilities from global objects like fetch or from modules like net. Any dependency you install can, by default, reach those globals. That is the supply chain problem in its most ordinary form: not a malicious package, but a package with a transitive dependency that reads the network.
LavaMoat generates reviewable policies that determine what capabilities will be distributed to third-party dependencies according to evident need, and enforces those policies at runtime with Endo. The key word is reviewable.
So there are two separable products here. Endo itself is the substrate, and LavaMoat is a policy layer on top of it. A team that wants the protection but not the object-capability programming model can adopt the policy layer alone, and the documentation presents it as a companion tool rather than a part of Endo.
Endo also provides tooling for bundling and safely executing arbitrary programs in the presence of hardened platform objects, which is the plugin use case stated plainly.
The petname daemon, and the packages that make up the monorepo
Endo puts object capabilities directly into the hands of users through an example petname system called the Pet Daemon, so users can send, receive and use object-capabilities with human-meaningful names. The Endo Daemon and its CLI are what the project presents as the demonstration of the whole approach, combining confinement and communication in a confined plugin system.
The name is worth a note, because it is a good one. In Greek, endo- means internal or within, which is fitting because Endo runs Node within a safe sandbox, and fitting in turn because Endo is built on the legacy of Google Caja. In Spanish, caja means box and relates to the Latin capsum and English capsule, as in encapsulate. Endo is also an anagram of Node and Deno, with the project's own gloss being that we are not Done yet.
The repository is a yarn 4 monorepo with workspaces covering packages/*, and the packages publish under the @endo scope and under ses for the SES shim itself. Recent releases show the pattern: @endo/pass-style at 2.0.1 and @endo/evasive-transform at 2.3.1 on 2026-08-17, and ses at 2.3.0 on 2026-08-13. The packages directory contains a daemon package and a cli package, alongside the ses package that the documentation links to for the Agoric and MetaMask material.
The toolchain is visible in the root package.json, which is marked private because it is a monorepo root rather than a published package:
{
"private": true,
"useWorkspaces": true,
"workspaces": [
"packages/*"
],
"engines": { "node": ">=16" },
"packageManager": "[email protected]",
"type": "module"
}Node 16 or newer is required, the package manager is yarn 4.13.0, the type field is module, and the dev dependencies include the AVA test runner with several lockdown-related AVA configs, eslint with the @endo eslint plugin, typedoc for API documentation, and a type-coverage tool. The presence of separate AVA configs named for lockdown, shims-only and noop-harden variants tells you the test matrix deliberately covers different lockdown modes, since a security framework has to be tested against the case where the platform refuses to lock down.
Where the cost of Endo shows up
The first limitation is the cost of adoption for an application with no untrusted code. Lockdown is a global, one-way operation. It has to happen before anything else runs, it changes the behaviour of the whole environment, and code that patched a built-in prototype for a legitimate reason stops working. None of that is a reason not to use Endo, but it is a reason not to use it casually, and a team with a small internal app and a good dependency review process is paying for a threat model it does not have.
The second limitation is that the object-capability model is a programming discipline, not just an API. The guarantee that the only way to obtain a capability is to have received it means that every design decision has to be reviewed against that question, and a codebase written in the ambient authority style will not simply be wrapped. The framework does not give you confinement for free; it gives you the tools, and the migration is the work.
The third is that the distributed half is still in progress. OCapN is described as a thing to come, with CapTP as the concrete transport available now, and the Rust workspace contains exactly one member, the noise protocol implementation. If your requirement is a stable cross-network capability protocol, the choice today is CapTP and the surrounding machinery rather than a finished stack.
On maintenance, the repository is not archived, the last push was on 2026-10-15, and the licence is Apache-2.0 with a LICENSE file at the root and a SECURITY.md for reporting. The project is actively community driven, with weekly video calls, a mailing list, a Matrix channel, and participation in the ECMAScript Technical Committee TG-3 Security Working Group, which is unusual visibility for a security framework.
Editorial conclusion
Endo suits a team building a plugin platform, a web extension, or a smart contract system where third-party code must run with limited authority and where prototype pollution is a live risk. It is a poor fit for an ordinary application with no untrusted code, since lockdown and compartments cost real work to adopt and buy nothing without a hostile dependency. Before adopting, read the SES lockdown documentation in the packages directory, decide whether you need only in-process confinement or the full distributed story with eventual send and CapTP, and check the licensing of the individual packages you pull in, since the monorepo publishes many of them under separate versions.
Frequently asked questions
What is Endo and what problem does it solve?
Endo is a framework for JavaScript plugin systems and supply chain attack resistance, with tools for confinement, communication and concurrency. It defends program integrity both in-process and in distributed systems against attacks that enter through upgrades to third-party dependencies.
What are lockdown, harden and compartment in SES?
Lockdown freezes the shared intrinsics so they are safe to share between programs. Harden makes your own objects safe to share between compartments, and a compartment is the isolation unit with a curated set of globals. Together they give you the object-capability guarantees: capabilities cannot be forged, and a hardened object cannot be altered.
How does Endo handle object capabilities across a network?
Once a reference crosses a network the guarantee rests on cryptography rather than JavaScript memory safety, so a large, signed, cryptographically random number over an encrypted connection can designate a capability. Eventual Send is the transport-agnostic abstraction over those capability transport protocols, with CapTP as a concrete transport today and OCapN as the one to come.
What does LavaMoat add to Endo?
LavaMoat generates reviewable policies that determine which capabilities are distributed to third-party dependencies according to evident need, and enforces them at runtime with Endo. That is the answer to libraries that reach powerful globals like fetch or modules like net.
Who uses Endo in production?
The documentation names Agoric and MetaMask, which rely on Hardened JavaScript and the SES shim as part of systems that sandbox third-party plugins or smart contracts and mitigate supply chain attacks for production web applications, web extensions and build systems.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/endojs-endo)