1 executor sandbox
~larandar edited this page 2026-09-09 13:34:00 +02:00

← Home

executor-sandbox

Sandbox provisioning and enforcement. One sandboxed run is assembled from six cooperating layers into a single deterministic bwrap argv — SandboxSpec::bwrap_argv(host_env, command) — so callers and tests can inspect exactly what will run. Failures surface as executor_core::SandboxError.

The six layers

  • mounts — the NixOS mount table is probed, not assumed: --proc, --dev, private /tmp tmpfs, read-only binds of /nix/store and /run/current-system/sw, and the workspace bind at /workspace.
  • masking.dsh-run state directories and DSH_HOME are shadowed out of the sandbox (e.g. /dev/null over /workspace/.dsh-run). A host DSH_HOME never crosses the boundary.
  • containment--unshare-all, --unshare-net, --clearenv, and an environment whitelist: only explicitly allowed names (allow) or set pairs (set) pass through. Network access is off unless the policy turns it on; the default is contained.
  • socket — the supervisor RPC bridge at /run/wf.sock (env var WF_RPC_SOCK), length-framed request/response over a UNIX domain socket. This is the one sanctioned channel between a contained run and its supervisor — no network involved. Frames are bounded at 1 MiB.
  • lifecycle--unshare-pid with --die-with-parent; the supervisor command becomes PID 1 inside the namespace and reaps orphans before a clean exit.
  • reaper — the wall-clock deadline and ownership reaper law. A run has a wall-clock timeout; at expiry SIGTERM goes to proven PIDs only, a 5-second grace period (GRACE_PERIOD) elapses, then SIGKILL ends the survivors. Ownership is proven before any signal: record registers a PID, proven gates delivery.

Argv order is fixed

bwrap_argv composes the layers in one order, always: namespace flags, isolation flags, mounts, masks, RPC bridge, environment, then -- and the command. Same inputs produce a byte-identical argv — the property the crate's test pins.

Boundary in one example

Given a whitelisted WF_RUN_ID and a host DSH_HOME, the assembled argv binds the workspace, masks .dsh-run, passes --setenv WF_RUN_ID …, and never mentions DSH_HOME. That is the perimeter in visible form: whitelisted environment in, DSH internals masked, no network, supervisor as PID 1, reaper standing by.