4.6 KiB
PR#17: The sandbox's environment no longer stands on the command line of bwrap, nor in a file others can read
WARNING: This document describes only the change applied in this PR. It may already be outdated once the next PR is merged. Historic PR documentation is not maintained along with new PRs; treat it as a snapshot.
Related Links
- werkator PR#166: Werkator passes the values of a build's variables to werkdock through its environment.
Problem
werkdock passes each variable of the sandbox as bwrap --setenv KEY VALUE.
So every secret of a build stands in the argv of bwrap, e.g. the tokens of werkrevisor's ai-review build on mih09.
Each process that can read /proc/<pid>/cmdline sees them, and so does each ps, crash report or log of an argv.
On 2026-10-20 they leaked from pgrep -af on mih09 into a transcript.
Werkator passes the values to werkdock run through its environment since werkator PR#166, as a bare -e KEY;
bwrap's argv is the last place where they stand.
A second leak, found on mih09 the same day: each instance, also of an attached run --rm,
writes its configuration with the whole environment to instances/<id>/config.json, mode 0644, in a directory of mode 0755.
The other accounts of the group mih09 could read the four secrets of a running ai-review build there.
Non-Goals
- No change of what the sandbox sees:
the image's variables, the
-evalues and werkdock'sHOMEandPATH, nothing of the caller's environment. - No change of the instance layout; the files only change their mode.
config.jsonkeeps the environment in plain text, sincestartof a stopped instance needs it. With mode 0600 only the account reads it, and that account holds the secrets anyway, e.g. in Werkator's configuration.
Specification
Feature: the environment of a sandbox reaches it off the command line
Scenario#17.01: bwrap's command line holds no value of the sandbox's environment
… so that no ps and no log of an argv shows a secret of a build.
- Given a sandbox with the variable
API_KEYand a secret value - When werkdock starts it
- Then
/proc/<pid>/cmdlineof bwrap holds neither the value nor a--setenv- and the command in the sandbox sees the value
Verified by
Scenario#17.02: a large value reaches the sandbox whole
… so that a whole configuration file in a variable still works.
- Given a variable of 100,000 bytes
- When werkdock starts the sandbox
- Then the command sees all 100,000 bytes
- and holds no open descriptor of the pipe
Verified by
Scenario#17.03: an instance is readable by its owner only
… so that no other account reads the secrets of a build from its configuration or its logs.
- Given an instance whose environment holds a secret
- When werkdock creates and runs it
- Then its directory has mode 0700
- and
config.json,state.jsonand the logs have mode 0600
- and
Verified by
Solution
Argvends the environment with--clearenv --args 4; bwrap reads the--setenvarguments, NUL-separated, from fd 4.EnvArgswrites them;Startpasses a pipe as fd 4 and writes into it while bwrap reads. bwrap has had--args FDsince 0.1.x; mih09 and the workstation have 0.11.- A NUL byte in a key or a value is refused: it would split the value into further bwrap arguments.
- Not chosen: bwrap's own environment set to the sandbox's variables, as the task proposed.
bwrap runs on the host, so an
LD_PRELOAD,LD_LIBRARY_PATHorGCONV_PATHmeant for the sandbox would load a library of the build into bwrap, outside the sandbox.--argskeeps the semantics of--clearenvand--setenvexactly. - An instance directory is created with mode 0700, its JSON files and logs with 0600.
The
instances/directory itself stays as it is; each instance below it is closed. An instance created before 0.13.2 keeps its modes until it is removed; Werkator's builds remove theirs (--rm). - Red/green: with
--setenvback inArgv, both tests of Scenario#17.01 fail; with the old modes, Scenario#17.03 fails for each of its five paths. - Version 0.13.2 with a section in
CHANGELOG.md. docs/risk-analysis.mdnames the leak and its measure.
Open Questions
None.
Additional Changes
None.