# @suaveplan/api-sandbox-permissions - Permission model for sandboxed-tier API plugins. PermissionPolicy + PermissionChecker (fs/fetch/capability) + BudgetTracker + PERMISSION_DENIED / BUDGET_EXCEEDED error codes + OTel denial / budget instrument descriptors + runPermissionsConformance harness. Consumed by api-sandbox-vm and api-sandbox-wasm. Permission model for sandboxed-tier API plugins. Centralises the `permissions.fs[]` / `permissions.fetch[]` allowlists, the `permissions.budgets` enforcement, and the capability-payload gating that both sandbox hosts (`api-sandbox-vm`, `api-sandbox-wasm`) require. Per design doc §2.2 and §5.2b every sandboxed capability call passes through this layer before reaching the worker capability proxy. A deny increments `plugin.permission_denied_total{plugin, capability, reason}` and surfaces inside the plugin as `SandboxPermissionError` (`code: SAND_PERM.DENIED`). ## Documentation tree - [budget](./src/budget/budget.md) — This module owns the per-request resource-budget enforcement for the sandboxed tier. Sampling primitives (CPU percentag… - [budget](./src/budget/budget.md) — This module owns the per-request resource-budget enforcement for the sandboxed tier. Sampling primitives (CPU percentag… - [checker](./src/checker/checker.md) — This module is the composite entry point that the two sandbox hosts (`api-sandbox-vm`, `api-sandbox-wasm`) wire into th… - [capability](./src/checker/capability/capability.md) — This module gates the three capability surfaces whose grain is finer than a single host-proxy can express: database acc… - [capability](./src/checker/capability/capability.md) — This module gates the three capability surfaces whose grain is finer than a single host-proxy can express: database acc… - [fetch](./src/checker/fetch/fetch.md) — This module owns the `permissions.fetch[]` enforcement path. Every outbound HTTP call routed through the sandbox host M… - [fetch](./src/checker/fetch/fetch.md) — This module owns the `permissions.fetch[]` enforcement path. Every outbound HTTP call routed through the sandbox host M… - [fs](./src/checker/fs/fs.md) — This module owns the `permissions.fs[]` enforcement path. Every filesystem capability call routed through the sandbox h… - [fs](./src/checker/fs/fs.md) — This module owns the `permissions.fs[]` enforcement path. Every filesystem capability call routed through the sandbox h… - [checker](./src/checker/checker.md) — This module is the composite entry point that the two sandbox hosts (`api-sandbox-vm`, `api-sandbox-wasm`) wire into th… - [error-codes](./src/error-codes/error-codes.md) — This module owns the stable error-code registry for the `@suaveplan/api-sandbox-permissions` package. Every deny path r… - [error-codes](./src/error-codes/error-codes.md) — This module owns the stable error-code registry for the `@suaveplan/api-sandbox-permissions` package. Every deny path r… - [instruments](./src/instruments/instruments.md) — This module owns the OTel counter pair that every sandboxed-tier host emits on a deny / budget-breach path. Centralisin… - [instruments](./src/instruments/instruments.md) — This module owns the OTel counter pair that every sandboxed-tier host emits on a deny / budget-breach path. Centralisin… - [policy](./src/policy/policy.md) — This module owns the construction-time value object that holds the compiled allowlists derived from a `PermissionsManif… - [policy](./src/policy/policy.md) — This module owns the construction-time value object that holds the compiled allowlists derived from a `PermissionsManif… - [testing](./src/testing/run-permissions-conformance.md) — This module exports the `runPermissionsConformance(label, factory)` harness that every sandbox host (`api-sandbox-vm`,… - [run-permissions-conformance](./src/testing/run-permissions-conformance.md) — This module exports the `runPermissionsConformance(label, factory)` harness that every sandbox host (`api-sandbox-vm`,… ## Features - `PermissionPolicy` — compiled allowlists + resolved budgets, built once at registration time. Zod-validated at the ingestion boundary. - `PermissionChecker` — composite `checkFs / checkFetch / checkCapability` plus `assertFs / assertFetch / assertCapability` for the enforce-by-default surface. `mode: "warn"` for canary-phase reloads. - `BudgetTracker` — per-request CPU / memory / wall-clock breach detection. Idempotent across repeat samples on the same dimension. - `SAND_PERM.*` error code registry: `DENIED`, `BUDGET_EXCEEDED`. - OTel counter pair: `plugin.permission_denied_total`, `plugin.budget_exceeded_total`. - `runPermissionsConformance` harness on the `./testing` subpath — every sandbox host MUST pass it. ## Modules - [`src/policy/policy.md`](src/policy/policy.md) — `PermissionPolicy`, glob compiler, Zod ingestion schema. - [`src/checker/checker.md`](src/checker/checker.md) — composite `PermissionChecker` + `assert*` helpers. - [`src/checker/fs/fs.md`](src/checker/fs/fs.md) — pure `checkFs`. - [`src/checker/fetch/fetch.md`](src/checker/fetch/fetch.md) — pure `checkFetch`. - [`src/checker/capability/capability.md`](src/checker/capability/capability.md) — pure `checkCapability`. - [`src/budget/budget.md`](src/budget/budget.md) — `BudgetTracker`. - [`src/error-codes/error-codes.md`](src/error-codes/error-codes.md) — `SAND_PERM.*` registry. - [`src/instruments/instruments.md`](src/instruments/instruments.md) — OTel counter descriptors. - [`src/testing/run-permissions-conformance.md`](src/testing/run-permissions-conformance.md) — shared host conformance harness. ## Quick start ```ts import { PermissionChecker } from "@suaveplan/api-sandbox-permissions"; import { createPermissionInstruments } from "@suaveplan/api-sandbox-permissions/instruments"; import { PermissionPolicy } from "@suaveplan/api-sandbox-permissions/policy"; const policy = new PermissionPolicy({ permissions: { fs: ["./uploads/*"], fetch: ["api.stripe.com"], budgets: { wallClockMs: 30_000 }, }, }); const instruments = createPermissionInstruments({ plugin: "billing" }); const checker = new PermissionChecker({ policy, instruments }); const result = checker.checkFetch("https://api.stripe.com/v1/charges"); if (result.outcome === "deny") { // permission denied — host fabricates Deny envelope on the worker channel } ``` ## Dependencies Runtime: `@suaveplan/api-types`, `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/opentelemetry`, `@opentelemetry/api`, `tslib`, `zod`. No `@suaveplan/api-*` runtime beyond `api-types`.