Files
2026-06-09 21:06:27 +01:00

6.6 KiB

@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 — This module owns the per-request resource-budget enforcement for the sandboxed tier. Sampling primitives (CPU percentag…
    • budget — This module owns the per-request resource-budget enforcement for the sandboxed tier. Sampling primitives (CPU percentag…
  • checker — This module is the composite entry point that the two sandbox hosts (api-sandbox-vm, api-sandbox-wasm) wire into th…
    • capability — This module gates the three capability surfaces whose grain is finer than a single host-proxy can express: database acc…
      • capability — This module gates the three capability surfaces whose grain is finer than a single host-proxy can express: database acc…
    • fetch — This module owns the permissions.fetch[] enforcement path. Every outbound HTTP call routed through the sandbox host M…
      • fetch — This module owns the permissions.fetch[] enforcement path. Every outbound HTTP call routed through the sandbox host M…
    • fs — This module owns the permissions.fs[] enforcement path. Every filesystem capability call routed through the sandbox h…
      • fs — This module owns the permissions.fs[] enforcement path. Every filesystem capability call routed through the sandbox h…
    • checker — This module is the composite entry point that the two sandbox hosts (api-sandbox-vm, api-sandbox-wasm) wire into th…
  • error-codes — This module owns the stable error-code registry for the @suaveplan/api-sandbox-permissions package. Every deny path r…
    • error-codes — This module owns the stable error-code registry for the @suaveplan/api-sandbox-permissions package. Every deny path r…
  • instruments — This module owns the OTel counter pair that every sandboxed-tier host emits on a deny / budget-breach path. Centralisin…
    • instruments — This module owns the OTel counter pair that every sandboxed-tier host emits on a deny / budget-breach path. Centralisin…
  • policy — This module owns the construction-time value object that holds the compiled allowlists derived from a `PermissionsManif…
    • policy — This module owns the construction-time value object that holds the compiled allowlists derived from a `PermissionsManif…
  • testing — This module exports the runPermissionsConformance(label, factory) harness that every sandbox host (api-sandbox-vm,…
    • run-permissions-conformance — 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

Quick start

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.