🔒 Security
ES-Runtime runs JavaScript services inside a capability-based security boundary. This page explains how to report a vulnerability, what belongs in scope, and where to read each part of the runtime's security model.
Do not open a public GitHub issue for a suspected security vulnerability. Email security@opentechf.org and follow the private reporting process in the repository's SECURITY.md so a fix can be assessed before details are published.
Reporting a vulnerability
The fastest report answers three questions: what breaks, how to reproduce it, and what an attacker gains. Include:
Report privately to security@opentechf.org.
| Include | Why it helps |
|---|---|
| Affected version or commit | Identifies the code path and whether the issue is already fixed |
| Minimal reproduction | A few lines of JavaScript or a small project is easier to verify than a general description |
| Impact | Shows whether the result is a capability bypass, data disclosure, code execution, denial of service, or crash |
| Runtime and platform | Identifies OS, architecture, binary (esrun or esdev), and relevant flags |
The project is pre-1.0 and has no long-term-support branches. Keep deployments on the current release line and check SECURITY.md for the current status of known issues and accepted gaps.
Scope
In scope is a defect that lets untrusted JavaScript do something the host policy should prevent, or makes the runtime unsafe under hostile input:
bypassing a capability check or the filesystem root jail;
escaping a worker's attenuated permissions or using a foreign resource handle;
leaking environment values, filesystem contents, credentials, or key material;
remote code or module execution outside the command's explicit policy;
denial of service caused by unbounded host work, memory, recursion, or input;
memory-safety, FFI, parser, cryptographic, or supply-chain vulnerabilities.
Out of scope are vulnerabilities in an application that merely uses ES-Runtime, issues requiring an attacker to already control the host process or deployment command, and ordinary documentation or website bugs unless they expose credentials or change the security boundary.
Built-in hardening
The security boundary is in the native host, not in JavaScript:
| Protection | What it does |
|---|---|
| Deny-by-default capabilities | esrun reaches no host-facing operation until the launch command grants it. |
| Filesystem root jail | File and module paths are canonicalized and confined to the working directory. |
| Explicit import policy | --import-policy separately controls which packages and paths may become running code. |
| Resource limits | Heap, execution time, stack depth, pending host work, and worker memory are bounded or terminated. |
| Agent isolation | Workers have separate isolates and attenuated permissions; handles belong to their creating agent. |
| No remote modules | Network URLs cannot silently become executable modules. |
| Supply-chain gates | CI runs cargo deny check and cargo audit. |
esdev is intentionally permissive for development and grants everything by default. Deploy the built artifact with esrun, then state its minimum grant explicitly. Use esdev --trace-permissions to discover the capabilities a development run used.
Security guides
Choose the topic you need:
Permissions & capabilities — grants, scopes, denials, and resource ownership. This replaces the old
#granting-capabilities-in-esrunsection.Import policy — control which files and packages may become running code.
Processes and workers — child-process escape, worker isolation, and attenuated permissions.
Network security — outbound/listening grants and UDP's limits.
Filesystem and secrets — root jail,
.env, and secret masking.Cryptography and runtime hardening — password hashing, remote modules, and V8 confinement.
For the practical deployment method, see Securing the runtime.
Legacy links to the former capability section now continue through the Permissions & capabilities guide.