109 lines
8.6 KiB
Markdown
109 lines
8.6 KiB
Markdown
# @suaveplan/sandbox - Server-tier sandboxed code execution: node:vm, node:worker_threads, and node:child_process engines, pre-warmed pool, audit logger, sliding-window rate limiter, pattern-based code transformer, async result streamer.
|
|
|
|
Server-tier sandboxed code execution for `@suaveplan` plugin hosts and agent runtimes. Ships four `SandboxEngine` implementations (a `node:vm` default, real `node:worker_threads` for OS-thread isolation, real `node:child_process` for process isolation, and a structural `isolated-vm` adapter), a pre-warmed `SandboxPool`, an async `ResultStreamer`, a pattern-based `CodeTransformer`, an allowlist-based `ModuleResolver`, a sliding-window `ResourceLimiter`, and a SHA-256 `AuditLogger` — all behind a `createSandbox()` facade with Zod-validated config and full OpenTelemetry instrumentation.
|
|
|
|
<!-- begin:auto-docs -->
|
|
## Documentation tree
|
|
|
|
- [audit-logger](./src/audit-logger/audit-logger.md) — `AuditLogger` records every sandbox execution with a structured `AuditLogEntry`. Each entry carries an ISO-8601 timesta…
|
|
- [audit-logger](./src/audit-logger/audit-logger.md) — `AuditLogger` records every sandbox execution with a structured `AuditLogEntry`. Each entry carries an ISO-8601 timesta…
|
|
- [code-transformer](./src/code-transformer/code-transformer.md) — `CodeTransformer` is a defence-in-depth layer that pattern-matches dangerous code constructs before they reach the engi…
|
|
- [code-transformer](./src/code-transformer/code-transformer.md) — `CodeTransformer` is a defence-in-depth layer that pattern-matches dangerous code constructs before they reach the engi…
|
|
- [error-codes](./src/error-codes/error-codes.md) — `@suaveplan/sandbox` raises typed `SandboxError` instances rather than plain `Error` so consumers can discriminate fail…
|
|
- [error-codes](./src/error-codes/error-codes.md) — `@suaveplan/sandbox` raises typed `SandboxError` instances rather than plain `Error` so consumers can discriminate fail…
|
|
- [isolate-engine](./src/isolate-engine/isolate-engine.md) — `IsolateEngine` implements the `SandboxEngine` contract over a structural `IsolateFactory` interface that mirrors the `…
|
|
- [isolate-engine](./src/isolate-engine/isolate-engine.md) — `IsolateEngine` implements the `SandboxEngine` contract over a structural `IsolateFactory` interface that mirrors the `…
|
|
- [module-resolver](./src/module-resolver/module-resolver.md) — `ModuleResolver` is the gatekeeper between user code and the host's module surface. It maintains an allowlist of module…
|
|
- [module-resolver](./src/module-resolver/module-resolver.md) — `ModuleResolver` is the gatekeeper between user code and the host's module surface. It maintains an allowlist of module…
|
|
- [pool](./src/pool/pool.md) — `SandboxPool` amortises engine startup cost across many short executions by maintaining a warm pool of `SandboxEngine`…
|
|
- [pool](./src/pool/pool.md) — `SandboxPool` amortises engine startup cost across many short executions by maintaining a warm pool of `SandboxEngine`…
|
|
- [resource-limiter](./src/resource-limiter/resource-limiter.md) — `ResourceLimiter` enforces two complementary controls on the sandbox boundary: a sliding-window rate limit (so a single…
|
|
- [resource-limiter](./src/resource-limiter/resource-limiter.md) — `ResourceLimiter` enforces two complementary controls on the sandbox boundary: a sliding-window rate limit (so a single…
|
|
- [result-streamer](./src/result-streamer/result-streamer.md) — `ResultStreamer` delivers sandbox output incrementally rather than as a single end-of-execution dump. The most common u…
|
|
- [result-streamer](./src/result-streamer/result-streamer.md) — `ResultStreamer` delivers sandbox output incrementally rather than as a single end-of-execution dump. The most common u…
|
|
- [sandbox](./src/sandbox/sandbox.md) — `createSandbox` is the public entry point of the package. It composes the engine, `ModuleResolver`, `ResourceLimiter`,…
|
|
- [sandbox](./src/sandbox/sandbox.md) — `createSandbox` is the public entry point of the package. It composes the engine, `ModuleResolver`, `ResourceLimiter`,…
|
|
- [schemas](./src/schemas/schemas.md) — Zod schemas guard every public boundary of `@suaveplan/sandbox`. The package never trusts its caller; instead, every ar…
|
|
- [schemas](./src/schemas/schemas.md) — Zod schemas guard every public boundary of `@suaveplan/sandbox`. The package never trusts its caller; instead, every ar…
|
|
- [spawn-engine](./src/spawn-engine/spawn-engine.md) — `SpawnEngine` uses `node:child_process.spawn` for the strongest isolation the package offers: a fresh OS process spawne…
|
|
- [runner](./src/spawn-engine/runner.md) — `runner.ts` is the child-process entry point invoked by `SpawnEngine`. The parent process spawns it via `node:child_pro…
|
|
- [spawn-engine](./src/spawn-engine/spawn-engine.md) — `SpawnEngine` uses `node:child_process.spawn` for the strongest isolation the package offers: a fresh OS process spawne…
|
|
- [telemetry](./src/telemetry/telemetry.md) — `@suaveplan/sandbox` ships first-class OpenTelemetry instrumentation so consumers running the sandbox at any scale can…
|
|
- [telemetry](./src/telemetry/telemetry.md) — `@suaveplan/sandbox` ships first-class OpenTelemetry instrumentation so consumers running the sandbox at any scale can…
|
|
- [vm-engine](./src/vm-engine/vm-engine.md) — `VmEngine` is the default sandbox engine. It uses `node:vm` directly: caller code is compiled with `new vm.Script(...)`…
|
|
- [vm-engine](./src/vm-engine/vm-engine.md) — `VmEngine` is the default sandbox engine. It uses `node:vm` directly: caller code is compiled with `new vm.Script(...)`…
|
|
- [worker-engine](./src/worker-engine/worker-engine.md) — `WorkerEngine` uses real `node:worker_threads` for true OS-thread isolation. Each `execute` call spawns a fresh `Worker…
|
|
- [worker-engine](./src/worker-engine/worker-engine.md) — `WorkerEngine` uses real `node:worker_threads` for true OS-thread isolation. Each `execute` call spawns a fresh `Worker…
|
|
<!-- end:auto-docs -->
|
|
|
|
## Install
|
|
|
|
```bash
|
|
bun add @suaveplan/sandbox
|
|
```
|
|
|
|
## Quick start
|
|
|
|
```ts
|
|
import { createSandbox } from "@suaveplan/sandbox";
|
|
|
|
const sandbox = createSandbox({ timeout: 5000, engine: "vm" });
|
|
const result = await sandbox.execute("2 + 3");
|
|
console.log(result.result); // 5
|
|
sandbox.destroy();
|
|
```
|
|
|
|
## Engine selection
|
|
|
|
| Engine | Boundary | Use when |
|
|
|---|---|---|
|
|
| `vm` (default) | `node:vm` context | Trusted accident-isolation, fastest path. |
|
|
| `worker` | `node:worker_threads` | Adversarial code, OS-thread isolation. |
|
|
| `spawn` | `node:child_process` | Adversarial code, full process isolation. |
|
|
| `isolate` | `isolated-vm` (optional dep) | Strongest in-process isolation. |
|
|
|
|
Wire `engine: "isolate"` with a `customEngine` factory that constructs a real
|
|
`IsolateEngine` over your installed `isolated-vm` peer dependency.
|
|
|
|
## Modules
|
|
|
|
Co-located docs for every public surface:
|
|
|
|
- [error-codes](./src/error-codes/error-codes.md) — `SANDBOX_CODES`,
|
|
`SandboxError`.
|
|
- [schemas](./src/schemas/schemas.md) — Zod boundaries.
|
|
- [telemetry](./src/telemetry/telemetry.md) — OTel instruments + recorders.
|
|
- [audit-logger](./src/audit-logger/audit-logger.md) — execution audit log.
|
|
- [resource-limiter](./src/resource-limiter/resource-limiter.md) —
|
|
rate-limit + output truncation.
|
|
- [module-resolver](./src/module-resolver/module-resolver.md) —
|
|
denylist/allowlist + builtins.
|
|
- [code-transformer](./src/code-transformer/code-transformer.md) —
|
|
regex-based dangerous-pattern guard.
|
|
- [vm-engine](./src/vm-engine/vm-engine.md) — default engine.
|
|
- [worker-engine](./src/worker-engine/worker-engine.md) — OS-thread engine.
|
|
- [spawn-engine](./src/spawn-engine/spawn-engine.md) — process engine.
|
|
- [runner](./src/spawn-engine/runner.md) — spawn-engine child entry point.
|
|
- [isolate-engine](./src/isolate-engine/isolate-engine.md) — `isolated-vm`
|
|
structural adapter.
|
|
- [pool](./src/pool/pool.md) — pre-warmed engine pool.
|
|
- [result-streamer](./src/result-streamer/result-streamer.md) — async
|
|
streaming output.
|
|
- [sandbox](./src/sandbox/sandbox.md) — `createSandbox` facade.
|
|
|
|
## Security model
|
|
|
|
`vm-engine` shares the host realm and is NOT a security boundary against
|
|
adversarial code — `vm.runInContext` can be escaped via prototype-chain
|
|
tricks. For adversarial isolation, use `worker-engine` or `spawn-engine`,
|
|
both of which sit behind real OS-level boundaries. The `code-transformer`
|
|
is a defence-in-depth layer that catches the obvious accidents
|
|
(`process.exit`, `require`, `eval`, etc.); it is not a substitute for an
|
|
engine-level boundary.
|
|
|
|
## Tier
|
|
|
|
Server (`node:vm` / `node:worker_threads` / `node:child_process` / `node:crypto`).
|
|
Targets Node ≥ 20 (and Bun, which provides the same APIs).
|
|
|