Files
deepseek-harness/packages/sandbox/sandbox-local

@deepseek-ai/dsh-sandbox-local

Local implementation of the @deepseek-ai/dsh-sandbox seam: wraps a caller's argv in a platform confinement runner. Selection is BY PLATFORM, resolved once and cached: each platform names its runner chain, a chain of one is selected directly (probing arbitrates between candidates — a sole candidate leaves nothing to arbitrate), and a chain of several is probed functionally in preference order. Linux: bwrap when its probe passes, else the landlock-run Landlock launcher (kernel confinement that needs no userns/mount privileges — see the sandbox RFC for the prebuilt-binary decision and profile-parity notes); darwin: sandbox-exec speaking a Seatbelt (SBPL) profile, unprobed. A platform with no chain means confine() FAILS CLOSED with the seam's structured SANDBOX_UNAVAILABLE error (win32 today: a reserved, deliberately empty chain awaiting an AppContainer-family runner); an unprobed runner that turns out unusable fails closed at EXECUTION instead — it refuses to run the command, and every wrap's runnerFailureSignatures let the consumer classify that as a sandbox failure rather than a task failure. Never a silent unconfined passthrough on any path.

Policy is per call (SandboxPolicy: mode + workspace root); the provider holds only the mechanism and the cached ladder verdict. Every wrap reports the selected runner's enforcement (full, or partial on an older Landlock ABI that governs only a subset of accesses — read from the launcher's --probe report line) and its denialSignatures — the stderr dialect that rung's kernel speaks on a denied file effect (EROFS text under bwrap, EACCES under Landlock, EPERM under Seatbelt), which stderr-inferring consumers match instead of a cross-runner union. A non-empty runnerCommand config is the operator's assertion of a runner that fully enforces the bwrap-shaped profile: the ladder and probes are skipped (the wrap carries both Linux denial dialects, the mechanism being unknown) — also the deterministic fake-runner seam for keyless test tiers. Its runner-failure dialect is the OUTER shell's argv0-scoped failure shapes (exec: <argv0>: not found, <argv0>: No such file or directory, <argv0>: Permission denied) — the consumer re-joins the wrap through bash -c 'exec …', so a missing or unexecutable configured runner classifies as a sandbox failure (fail closed at execution), never as a failing command or a denial. probeTimeoutMs (default 5000) bounds each functional probe, the escape hatch for hosts slow enough that a timed-out probe would otherwise misread as SANDBOX_UNAVAILABLE.

The Seatbelt profile is allow-default with (deny file-write*) plus write allow-lists, so exactly the mode's promised file effects are governed: read-only grants the /dev/null literal alone; workspace-write adds the workspace root, /tmp, and the per-user darwin temp dir (os.tmpdir() — the platform's real temp area for mkstemp-family tools), every root canonicalized because Seatbelt matches resolved paths (/tmp IS /private/tmp). Apple marks the sandbox-exec CLI deprecated but ships it on every macOS; the functional probe is what fails closed if that ever changes.

The Landlock launcher comes from the npm package family node-addon-landlock-run — an entry package (this package's one runtime dependency) plus per-platform binary packages selected by npm's os/cpu fields, built and released from its own repository. The entry package owns the launcher's CLI contract: launcherPath() resolution (a host with no platform package yields a never-existing path whose probe fails exactly like an unenforcing kernel), the functional probe(), and grantArgs() flag spelling — versioned together with the binary, so probe-report parsing can never drift against it. This provider keeps only the policy side: the mode → grants mapping (landlockProfileArgs) and the ladder. The consumer path is rehearsed by tests/packed-install.e2e.ts: pack THIS package's closure, install into a throwaway consumer with the launcher family coming from the registry, assert the installed binary executable (a stripped mode bit must not masquerade as a non-enforcing kernel), and confine through it under plain node.

Every rung has its keyless world-proof (tests/bwrap.e2e.ts, tests/landlock.e2e.ts, tests/seatbelt.e2e.ts), each self-skipping where its runner is absent; CI's sandbox-e2e matrix runs all of them against real kernels (bwrap plus one Landlock leg per architecture on Linux, Seatbelt on macOS) and fails on a silent all-skip.

- id: sandbox
  name: '@deepseek-ai/dsh-sandbox-local'

Consumers: @deepseek-ai/dsh-bash-sandbox; see examples/sandbox-acp-agent for the runnable composition.

Model Experience

Context surface What the model sees Token effect
Sandbox result facts, indirectly This provider adds no prompt or tool. It supplies the selected enforcement and denial dialect to dsh-bash-sandbox, which can become that consumer's exact [sandbox: file access denied under <mode> mode] marker. If no local runner can confine the command, the model instead receives the exact SANDBOX_UNAVAILABLE text quoted in dsh-sandbox. Runner selection and profiles are not shown. Zero direct tokens; only the conditional marker or error reaches context through the bash consumer.

Known Limitations and Deferred Work

  • Windows has no runnerwin32 fails closed with SANDBOX_UNAVAILABLE; an AppContainer-family backend is deferred.
  • Landlock may be partial — older supported kernel ABIs confine only the access classes they expose, reported as enforcement: 'partial' rather than overstated as full.
  • Seatbelt depends on deprecated sandbox-exec — macOS still ships it, but this provider cannot replace or probe that private policy engine if Apple removes it.
  • Runner selection is cached for the provider lifetime — installing, removing, or repairing a runner requires reloading the plugin before selection changes.
  • runnerCommand is an operator assertion — a configured custom runner skips functional probes and is assumed to implement the bwrap-shaped profile honestly.