From 5fe0848707bc60d1206e2b452ba72b7454674ed5 Mon Sep 17 00:00:00 2001 From: Sam & Claude Date: Sun, 14 Jun 2026 01:38:30 +0200 Subject: [PATCH] docs: document jail root_path + staged env payloads Match the docs to the shipped staged-env code: add the JailConfig root_path field, a 'Staged env payloads' section (prepare_spawn_command writes env.sh/ launch.sh under /var/run/colibri-stage//), resolve the mdo-env-passthrough open item, and add root_path to the external-MCP example. Co-Authored-By: Claude Opus 4.8 --- docs/COLIBRI-EXTERNAL-MCP-PROTOTYPE.md | 2 +- docs/COLIBRI-JAILED-AGENT-SPAWN-DESIGN.md | 23 +++++++++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/docs/COLIBRI-EXTERNAL-MCP-PROTOTYPE.md b/docs/COLIBRI-EXTERNAL-MCP-PROTOTYPE.md index a11b8c3..5cfd097 100644 --- a/docs/COLIBRI-EXTERNAL-MCP-PROTOTYPE.md +++ b/docs/COLIBRI-EXTERNAL-MCP-PROTOTYPE.md @@ -43,7 +43,7 @@ Schema: "env": { "DEMO_MODE": "1" }, - "jail": { "name": "mcp0" } + "jail": { "name": "mcp0", "root_path": "/usr/local/bastille/jails/mcp0/root" } } } } diff --git a/docs/COLIBRI-JAILED-AGENT-SPAWN-DESIGN.md b/docs/COLIBRI-JAILED-AGENT-SPAWN-DESIGN.md index a014b7e..1c8b15b 100644 --- a/docs/COLIBRI-JAILED-AGENT-SPAWN-DESIGN.md +++ b/docs/COLIBRI-JAILED-AGENT-SPAWN-DESIGN.md @@ -24,6 +24,9 @@ as before. The field that is set picks the jail lifecycle: - **`path`** — create an **ephemeral** jail with `jail -c … command=`, which exists only while the agent runs and is removed when it exits (no teardown needed). +- **`root_path`** — host-visible root path for a named jail; required when staged + env/working-dir payload delivery is needed. Falls back to `path` for ephemeral + jails. - optional `ip4` (`inherit` by default) and `user` (in-jail user, `jexec` path). `jail_wrap()` turns `(binary, args)` into the `(program, argv)` to exec. stdio is @@ -53,19 +56,31 @@ just `jexec`. We choose the escalation per host via `PrivMode` keep the daemon unprivileged. - **`none`** — run the jail command directly (already root, or tests). +## Staged env payloads + +When a jailed spawn needs env vars or a working dir, `prepare_spawn_command()` +writes a 0600 `env.sh` (sorted, single-quoted exports) and a `launch.sh` wrapper +into a staged directory under the jail's `root_path` at +`/var/run/colibri-stage//`. The jail command runs `/bin/sh launch.sh`, which +sources the env file and `cd`s to the working dir before `exec`-ing the agent +binary. This bypasses the env-passthrough problem entirely — no reliance on +`jexec`/`mdo` inheriting env vars. + +The staged directory is cleaned up when the agent stops, fails, exits early, or +encounters a poll error. The same mechanism is used by the external-MCP host for +jailed MCP servers. + ## Open items - **Teardown:** ephemeral `jail -c command=` self-cleans; reaping a deeply nested in-jail process tree may want a process-group kill (follow-up). -- **mdo env passthrough:** verify on FreeBSD that `mdo` propagates the injected - `COLIBRI_*` / provider env into the jailed process; if not, pass via `jexec` - args or a 0600 env file. - **Jail filesystem provisioning** (ISO / deploy): the jailed binary needs its runtime + work dir — a pre-provisioned persistent jail, or nullfs mounts for an ephemeral one. ## References -- `crates/colibri-daemon/src/spawner.rs` — `JailConfig`, `PrivMode`, `jail_wrap` +- `crates/colibri-daemon/src/spawner.rs` — `JailConfig`, `PrivMode`, `jail_wrap`, + `prepare_spawn_command`, `PreparedSpawnCommand` - `crates/colibri-daemon/src/lib.rs` + `socket.rs` — `jail` on the spawn-agent command - `crates/colibri-mcp/src/external.rs` — jailed external MCP servers -- 2.45.3