Files
deepseek-harness/packages/sandbox/sandbox-local
Yichen Jiang a90ccc4453 revert(sandbox): withdraw the credential-document read denial
The `readDenyPaths` policy field shipped in the previous commit broke Linux
confinement outright. bwrap has to create the `/dev/null` bind's mount point
inside a tree its own profile has already made read-only, so it refused the
entire confinement whenever the parent directory was absent — every host that
has not stored a credential yet, including a fresh install:

  bwrap: Can't mkdir parents for /home/runner/.dsh/.env: Read-only file system

which the executor correctly classifies as SANDBOX_UNAVAILABLE, so every
confined bash call failed closed. Landlock cannot subtract from its own `/`
read grant, so it reported `partial` enforcement on every confined call for a
file it never hid, with no way to switch the denial off (schemastery fills an
omitted array with `[]`, so empty and omitted were indistinguishable).

A protection that breaks confinement where it works and misreports it where it
does not is worse than a documented absence. Revert the field, both expressible
backends, the enforcement downgrade, and the policy default; state the residue
plainly in the credentials-local READMEs — file mode stops other OS users, not
the model — and keep the OS-keychain provider recorded as the real answer.

The narrower discipline stands: no surface hoists the credential document into
`process.env`, and the model is never handed a resolved path to it.
2026-07-30 17:09:42 +08:00
..
2026-07-26 05:06:39 +08:00

@deepseek-ai/dsh-sandbox-local

English | 中文

Local implementation of the dsh-sandbox seam. It selects and caches one platform runner: Linux prefers a working bwrap then Landlock; macOS uses Seatbelt. Multiple candidates are probed in order, while a sole candidate is selected directly.

The package root exports the default and named LocalSandboxProvider plugin, Config, and its public test-injection seam; platform profile builders stay internal.

Unsupported platforms and unusable runners fail closed with SANDBOX_UNAVAILABLE; execution never silently falls through unconfined. Each wrap carries runner-failure signatures so consumers can distinguish a broken sandbox from a command failure. The sandbox Agent Note owns selection rationale and profile differences.

Policy is per call; the provider stores only the mechanism and cached runner verdict. Each wrap reports enforcement completeness plus backend-specific denial and runner-failure signatures. runnerCommand is an operator assertion of a bwrap-shaped runner and skips probes, but missing or unexecutable commands still fail closed at execution. Because its mechanism is unknown, it carries both Linux denial dialects. probeTimeoutMs bounds functional probes. The sandbox Agent Note owns selection and failure semantics.

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.

node-addon-landlock-run supplies the platform launcher, functional probe, and CLI argument vocabulary. This provider owns only mode-to-grant mapping and runner selection. Keeping path resolution and probe parsing with the versioned binary prevents contract drift.

Each rung has a self-skipping keyless world-effect test; CI runs platform legs against real kernels and rejects a silent all-skip. The packed-install test exercises the registry launcher and executable mode through a plain-Node consumer.

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

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

Model Experience

Indirectly, through dsh-bash-sandbox and dsh-tool-bash, which render this provider's enforcement and denial facts while the dsh-sandbox seam owns the SANDBOX_UNAVAILABLE text and runner selection and profiles stay outside context.

KV Cache effect

No direct invalidation; the named consumer owns any request-prefix changes.

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.