# @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}`. ## 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… ## 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