100 lines
6.6 KiB
Markdown
100 lines
6.6 KiB
Markdown
# @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`).
|
|
|
|
<!-- begin:auto-docs -->
|
|
## 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`,…
|
|
<!-- end:auto-docs -->
|
|
|
|
## 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`.
|
|
|