Confined command runner
runConfinedCommand runs one command inside the same confinement the engine uses for its own sandboxed
processes. It is a supported public seam over existing pieces: the kernel bubblewrap invocation builder,
the sandbox posture decision, the egress proxy allowlist and the confined process lifecycle. It adds no
confinement logic of its own, so a command gets exactly the namespaces, dropped capabilities
and restrictions the engine applies elsewhere. Tools the kernel dispatches get the
same set (see Native kernel confinement).
Options
Section titled “Options”| Option | Meaning |
|---|---|
command, args | The program and its arguments. Use an absolute path, or a program found on the default PATH. |
cwd | Working directory. When confined it must lie inside one of the mounts. |
mounts | Extra mounts, each { path, mode: 'ro' | 'rw' }. A path is absolute and canonical (no symlink in it) and is bound at the same path. |
env | The only environment the command sees, plus PATH=/usr/bin:/bin unless you set it. Nothing is inherited from the calling process. |
network | 'off' (default) leaves the command with only a loopback interface. { allowlist, forwarderPath } is described below. |
limits | wallTimeoutMs (default none), maxStdoutBytes and maxStderrBytes (default 1 MiB each). |
signal | An AbortSignal that ends the whole process tree. |
securityEventEmitter | Optional. Receives the launch’s sandbox:admission events (its engine admission verdict and typed reasons), and is forwarded to the allowlist proxy it starts. Observation only: nothing about the launch changes. |
recordAdmission | Optional. Receives the launch’s admission record (SurfaceAdmissionRecord). Observation only. |
The system directories /usr, /bin, /sbin, /lib, /lib64 and /etc are always bound read-only.
Anything else the command needs, including a Node toolchain, must be listed in mounts. A write outside
the rw mounts, or to an ro mount, fails inside the command.
Handle and result
Section titled “Handle and result”The returned handle exposes pid, streamed stdout and stderr, confined, posture, wait() and
stop().
wait()resolves, and never rejects, once the command has exited and its output was delivered, withcode,signal,timedOut(the wall timeout fired),truncated(a stream exceeded its cap),aborted(the signal orstop()ended it),confined,postureandstderrTail.- An output stream delivers at most its cap. Bytes beyond it are discarded while the pipe keeps draining, so the command is never blocked by a full pipe and memory stays bounded.
stop()ends the command and everything it started, whatever stage of start-up it is in. It is bounded and idempotent: every call returns the same result.- A timeout, an abort and
stop()all end the whole tree, including processes the command started in the background.
Network allowlist
Section titled “Network allowlist”network: { allowlist: ['registry.example.test:443'], forwarderPath } lets the command reach only the
listed exact host:port pairs, through the confined egress proxy. Entries follow the per-job allowlist
grammar (exact host and port, no bare host, wildcard or CIDR) and an invalid entry rejects the call with
proxy.job-allowlist.* before anything starts. The proxy still vets every resolved address.
forwarderPath is the path of the standalone forwarder bridge that ships with the CLI package; the host
package never depends on the CLI, so the caller supplies it. onDenied receives each denial, and
violations maps each denial to a kernel sandbox:violation event. The command needs the Node toolchain
mounted read-only, as for any other program outside the system directories.
Where confinement is unavailable
Section titled “Where confinement is unavailable”Confinement needs Linux (x64 or arm64) with a working bwrap that supports the required flags. Elsewhere
runConfinedCommand rejects with confinement.refused and the posture reason, before anything is
spawned. A network allowlist is refused without confinement
(confinement.allowlist-requires-confinement), because nothing would enforce it.
Refusal codes
Section titled “Refusal codes”| Code | Cause |
|---|---|
confinement.refused | The posture is not enforced. |
confinement.allowlist-requires-confinement | An allowlist was requested for an unconfined run. |
confinement.mount-not-absolute | A mount path is not absolute. |
confinement.cwd-not-mounted | cwd is not inside any mount. |
confinement.env-name-invalid | An env name is not a valid variable name. |
confinement.limit-invalid | A limit is not a positive integer. |
confinement.aborted | The signal was already aborted. |
confinement.proxy-not-ready | The allowlist proxy did not report ready. |