Repository navigation
fix(container-gateway-hook): start the gateway on demand before a container command - #1814
Merged
Merged
Conversation
potiuk
marked this pull request as draft
October 25, 2026 14:52
potiuk
marked this pull request as ready for review
October 25, 2026 15:25
…tainer command The gateway exits mid-session after its idle timeout, when another session on the same project ends, or on a crash, and only SessionStart ever started it again. A new ensure action, wired as a PreToolUse hook on Bash, starts it before a docker/podman command, after the same trust checks as start. Generated-by: Claude Opus 5
main's prek has failed on this file since apache#1815. Generated-by: Claude Code (Claude Opus 5)
…nt's cwd The payload's cwd follows the agent's cd: before every tool call, and at the SessionStart that follows a compaction, /clear or resume. Judged from another directory, the session project's own write grants went uncounted, so a sandboxed cd elsewhere could get a source or interpreter the sandbox can write past the trust checks. Every action now takes the directory from CLAUDE_PROJECT_DIR, which Claude Code sets on every hook to the directory the session started in; it does not follow cd, and a settings env entry cannot override it (checked against Claude Code). start and stop fall back to the payload's cwd when it is unset; ensure does nothing. The payload's cwd and its settings are counted as writable too. Generated-by: Claude Code (Claude Opus 5)
potiuk
force-pushed
the
fix/container-gateway-on-demand
branch
from
October 25, 2026 16:09
117039b to
64262c5
Compare
potiuk
enabled auto-merge (squash)
October 25, 2026 16:13
10 of 17 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The container gateway is started only by the
SessionStarthook, but it can exit while the session still needs it:SessionEndstops the one gateway both share;From then on every sandboxed
docker/podmancommand fails withdial unix …/docker.sock: connect: no such file or directory, until the next session. Seen in an adopter repo: Docker Desktop was up, the gateway was gone, and the log showed no start since the session began.New
container-gateway-hook.sh ensureaction, wired as aPreToolUsehook onBashwith twoiffilters,Bash(docker *)andBash(podman *). Theiffilter is best-effort, so the script checks the command itself too.docker/podman(or the-composevariants) exits before any other work, in about 10 ms.startvetted for this session.startrecords it by session id under~/.claude/magpie-gateway/sessions/, where the sandbox cannot write, and the hook refuses to run if any grant covers that directory.ensurenever uses the payload'scwd, which follows the agent'scd: judged from another directory, the session project's own write grants would go uncounted, and a source or interpreter the sandbox can write could pass as trusted. With no record, it does nothing.stopdrops the record, and records older than 30 days are pruned.startruns (trusted interpreter and gateway source, writable roots, worktree records), so an on-demand start can run nothing thatstartwould refuse.statuswhether it is serving. If not, it starts it and waits up to 5 s for it to serve, so the triggering command does not race the start.serve --daemonreturns before the sockets are bound.The
SessionStart/SessionEndpair is unchanged and still starts the gateway with the session.Docs and RFC:
secure-agent-setup.md(registration example, migrationjq), the tool README /tool.md, the agent-isolation README, and sandbox troubleshooting.isolated-setup-installL.2 wires the new hook.isolated-setup-verify12a reports a missingensurehook as ◐, since start/stop alone still work, andisolated-setup-updatereports it as drift.ensurehook.isolated_fingerprint.pyand twomeasured_tokensstamps are regenerated by their hooks.Type of change
.claude/skills/<name>/) — eval fixtures updated belowtools/<system>/*.md)tools/*/withpyproject.toml)docs/,README.md,CONTRIBUTING.md)projects/_template/)prek, workflows, validators)Test plan
tools/agent-isolation/tests/test_container_gateway_hook.py:ensurestarts the gateway fordocker/podman/ compose commands, including aftercd x &&,;, a path prefix, aVAR=prefix, or inside( … ).cat Dockerfile,vim docker.mdand./mydocker.startdoes.MAGPIE_CONTAINER_GATEWAY_ARGS.cdelsewhere, it serves the session's recorded project and still counts that project's grants. Both tests fail against the first commit.../x,/etc/passwd), or for a symlinked record.startrecords the session,stopdrops the record, and a refusedstartrecords nothing.uv run pytest tests/test_container_gateway_hook.pyintools/agent-isolation: all 115 pass, outside the sandbox (the suite skips under the sandbox scratch dir).ensurewith anlspayload: no-op, 0.01 s;ensurewith adocker runpayload: gateway started and serving, 0.75 s;ensureagain: 0.54 s;docker run --rm alpine:3 echo …then succeeded.prek run --all-filesin CIRFC-AI-0004 compliance
Linked issues
Follows #1298 (container gateway) and #1797 (per-machine hook registration).
Notes for reviewers (optional)
ensuretook the project from the per-commandcwd, so a sandboxedcdinto another directory could make the session project's write grants go uncounted.ensurenow serves only the directorystartvetted for the session. A session that began before the hook was wired gets nothing fromensureuntil its next start.isolated-setup-updateproposes it as drift.🤖 Generated with Claude Code