Files
skills/docs/api-stack/api/api-sandbox-wasm/README.md
2026-05-29 08:20:56 +01:00

102 lines
5.9 KiB
Markdown

# @suaveplan/api-sandbox-wasm - WASM-based sandbox host for Suaveplan sandboxed-tier API plugins. Instantiates a WebAssembly module against a WASI snapshot preview1 implementation built from the plugin manifest's PermissionPolicy: read-only fs preopens by default (rw: prefix opt-in), outbound socket allowlist from permissions.fetch[], and capability host imports gated by PermissionChecker. Denials raise SAND_WASM_* errors and increment plugin.permission_denied_total. Ships ./testing conformance harness so every sandbox host satisfies the same WASI-specific invariants.
Stage-8 WebAssembly sandbox host. Instantiates a sandboxed-tier plugin
WASM module against a WASI snapshot preview1 implementation derived from
the plugin's `PermissionPolicy`:
- **`permissions.fs[]`** maps to read-only WASI preopen directories.
Write access requires the `rw:` rule prefix.
- **`permissions.fetch[]`** maps to an outbound socket allowlist; the
`sock_connect` host import refuses non-matching destinations BEFORE
opening an OS socket.
- **Capability imports** (under `suaveplan_caps`) are permission-gated
per call; denials return a WASI errno to the guest AND increment
`plugin.permission_denied_total{plugin, capability, reason}`.
<!-- begin:auto-docs -->
## Documentation tree
- [error-codes](./src/error-codes/error-codes.md) — Defines the stable `SAND_WASM.*` error-code registry and the `SandWasmError` subclass thrown by every production path i…
- [error-codes](./src/error-codes/error-codes.md) — Defines the stable `SAND_WASM.*` error-code registry and the `SandWasmError` subclass thrown by every production path i…
- [install-capability-imports](./src/imports/install-capability-imports/install-capability-imports.md) — Wraps every host-supplied capability proxy in a permission check so the guest's call goes through `PermissionCheckerLik…
- [install-capability-imports](./src/imports/install-capability-imports/install-capability-imports.md) — Wraps every host-supplied capability proxy in a permission check so the guest's call goes through `PermissionCheckerLik…
- [otel](./src/otel/otel.md) — Owns the WASM sandbox host's OpenTelemetry instrument registry. Every counter the host emits on a production path lives…
- [otel](./src/otel/otel.md) — Owns the WASM sandbox host's OpenTelemetry instrument registry. Every counter the host emits on a production path lives…
- [outbound](./src/outbound/outbound.md) — Builds the outbound-socket allowlist from `policy.fetch[]` and wraps the host's `connect` adapter so denied destination…
- [outbound](./src/outbound/outbound.md) — Builds the outbound-socket allowlist from `policy.fetch[]` and wraps the host's `connect` adapter so denied destination…
- [policy](./src/policy/policy.md) — Defines the `PermissionPolicy` value object and the `resolvePermissionPolicy` builder that lifts a `PermissionsManifest…
- [policy](./src/policy/policy.md) — Defines the `PermissionPolicy` value object and the `resolvePermissionPolicy` builder that lifts a `PermissionsManifest…
- [preopens](./src/preopens/preopens.md) — Maps `policy.fs[]` rules onto a WASI preopen table. The WASI capability model is file-descriptor-based: a guest can onl…
- [preopens](./src/preopens/preopens.md) — Maps `policy.fs[]` rules onto a WASI preopen table. The WASI capability model is file-descriptor-based: a guest can onl…
- [sandbox](./src/sandbox/sandbox.md) — Top-level entry point for the WASM sandbox host. `createWasmSandbox` compiles (or accepts a pre-compiled) WASM module,…
- [sandbox](./src/sandbox/sandbox.md) — Top-level entry point for the WASM sandbox host. `createWasmSandbox` compiles (or accepts a pre-compiled) WASM module,…
- [testing](./src/testing/run-wasm-conformance.md) — Exports `runWasmSandboxConformance(label, makeSandbox)` — the conformance harness every WASM-tier sandbox host (this pa…
- [run-wasm-conformance](./src/testing/run-wasm-conformance.md) — Exports `runWasmSandboxConformance(label, makeSandbox)` — the conformance harness every WASM-tier sandbox host (this pa…
- [wasi](./src/wasi/wasi.md) — Minimal `wasi_snapshot_preview1` snapshot tied to the sandbox host's permission policy. Every host-visible side effect…
- [wasi](./src/wasi/wasi.md) — Minimal `wasi_snapshot_preview1` snapshot tied to the sandbox host's permission policy. Every host-visible side effect…
<!-- end:auto-docs -->
## Install
```bash
bun add @suaveplan/api-sandbox-wasm
```
## Usage
```ts
import {
createWasmSandbox,
resolvePermissionPolicy,
} from "@suaveplan/api-sandbox-wasm";
const policy = resolvePermissionPolicy({
fs: ["./uploads/*", "rw:./tmp"],
fetch: ["api.stripe.com", "*.suaveplan.io"],
});
const handle = await createWasmSandbox({
pluginName: "stripe-checkout",
policy,
capabilities: [
{
capabilityId: "secrets",
importName: "secrets_get",
invoke: (...args) => secretsAdapter.get(args[0] as string),
},
],
checker,
wasmBytes: await readFile("./plugin.wasm"),
});
try {
const start = handle.instance.exports._start as () => void;
start();
} finally {
handle.dispose();
}
```
## Modules
- **error-codes** — `SAND_WASM_*` registry + `SandWasmError`.
- **policy** — `PermissionPolicy` value object + `resolvePermissionPolicy`.
- **preopens** — `buildWasiPreopens` + `matchPreopen`.
- **outbound** — `buildWasiOutboundAllowlist` + `gateOutboundConnect`.
- **wasi** — minimal `wasi_snapshot_preview1` snapshot with policy gating.
- **imports/install-capability-imports** — permission-gated host imports.
- **sandbox** — `createWasmSandbox` + `WasmSandboxHandle`.
- **otel** — `createSandWasmInstruments` (`plugin.permission_denied_total`).
- **testing** — `runWasmSandboxConformance` harness.
## Verification
```bash
bunx turbo lint typecheck test:coverage --filter=@suaveplan/api-sandbox-wasm
```
## License
MIT