Harness runtime files
How an agent harness gets its config/auth files (e.g. ~/.codex/config.toml,
~/.claude/...) into the sandbox without putting secrets on the wire.
Code: swarm/src/sandbox.py (render_runtime_files, _stage_home,
_safe_rel_path), app/executors/swarm.py::prefill_model_in_files.
The problem
Each agent CLI wants some files in $HOME to know its model + how to reach the
API. Those files often reference an API key. We must not ship the key through
pond → orchestrator → worker in clear, and the files must land inside the
sandbox’s $HOME, not the worker’s real home.
Templating + the two fill points
A harness declares runtime files as {path, content} templates with three
placeholders, filled at different trust points so no secret crosses the wire:
| Placeholder | Filled by | When |
|---|---|---|
{{MODEL}} | pond (dispatch) | prefill_model_in_files — non-secret, backend-known |
{{BROKER_URL}} | worker | at launch — the per-job broker address |
{{SECRET:NAME}} | worker | at launch — from the unsealed credential env |
So the templates that travel are secret-free; the worker fills {{BROKER_URL}}
and {{SECRET:NAME}} locally after unsealing the credential
(see model-credentials).
Materialization
render_runtime_files fills the placeholders and flags a file is_secret when
it consumed a {{SECRET:...}}. _stage_home writes them into a fresh per-job
$HOME (a temp dir the provider mounts at the sandbox $HOME), removed on
every exit path. Secret-bearing files are written 0600.
Preferred pattern is {{BROKER_URL}} + a dummy key, not {{SECRET:NAME}}:
under a brokered profile the real key lives only in the broker sidecar, so a
materialized real secret is redundant — _stage_home logs a warning when it
sees one on a brokered profile.
Path safety
_safe_rel_path rejects any runtime-file path that is absolute, starts with
~, or contains a .. segment; _stage_home additionally resolves the final
path and refuses anything that escapes the staged home. A harness template can
never write outside the per-job $HOME.
Invariants
- Templates on the wire never contain secrets;
{{SECRET}}/{{BROKER_URL}}are worker-local fills. - Runtime files land only in a disposable per-job
$HOME, removed after the run. - Secret-bearing files are
0600; the broker-redundant case is flagged. - No runtime-file path can escape
$HOME.