Jail agent commands in their own namespaces - #5
Merged
Merged
Conversation
ardecvz
marked this pull request as ready for review
September 15, 2026 04:13
There was a problem hiding this comment.
🔵 Needs a closer look
Unresolved critical jail-isolation and Docker-privilege findings require changes and human review.
Pull request overview
Adds jailed Miniswen execution, Docker sandbox changes, stricter verifier failures, tamper detection, longer retries, and release metadata updates.
Changes:
- Introduces namespace-based jail execution and enables it for
miniswen-installed. - Adds Docker capabilities and
iproute2support. - Treats restore failures and Minitest tampering as run failures.
- Extends model retry duration and updates documentation, tests, and versions.
File summaries
| File | Summary and review notes |
|---|---|
test/miniswen/jail_test.rb |
Tests jail isolation. |
test/miniswen/agent_test.rb |
Updates retry-budget coverage. |
test/lemans/trial/verifier_test.rb |
Updates restore-failure expectations. |
test/lemans/trial/snapshot_test.rb |
Tests restore failures. |
test/lemans/test_eport_lemans.rb |
Tests tamper-detection abort behavior. |
test/lemans/environments/test_docker.rb |
Tests Docker privilege flags. |
test/lemans/agents/test_miniswen_installed.rb |
Tests jailed command execution. |
README.md |
Documents the iproute2 dependency. |
lib/miniswen/version.rb |
Updates the Miniswen version. |
lib/miniswen/ruby_llm.rb |
Extends model-call retries to approximately 10 minutes. |
lib/miniswen/local.rb |
Refactors process spawning. |
lib/miniswen/jail.rb |
Implements namespace jail execution. Critical (3 votes): the unshare holder can expose provider credentials through /proc/1/environ; scrub its environment. Critical (2 votes): only selected directories are read-only while UID 0 can write other paths; make the root filesystem read-only with explicit writable mounts. Moderate (1 vote): non-root execution requires root or CAP_SYS_ADMIN. Moderate (1 vote): workdirs nested under replaced scratch mounts become inaccessible. Moderate (1 vote): direct requiring can produce missing-constant errors. |
lib/miniswen/cli.rb |
Adds jail lifecycle handling. Moderate (2 votes): --docker cleanup unconditionally calls unavailable stop, causing a post-run NoMethodError; stop only environments that own their lifecycle or provide a no-op. |
lib/lemans/version.rb |
Updates the Lemans version. |
lib/lemans/trial/verifier/assets/lemans_minitest_reporter.rb |
Detects Minitest assertion tampering. |
lib/lemans/trial/verifier.rb |
Propagates restore failures. |
lib/lemans/trial/snapshot.rb |
Makes restore failures raise infrastructure errors. |
lib/lemans/environments/docker.rb |
Adds jail-required Docker privileges. Critical (3 votes): CAP_SYS_ADMIN, CAP_NET_ADMIN, and AppArmor unconfined mode apply to every Docker sandbox, including runs that do not use the jail; restrict these privileges to jail-capable execution. |
lib/lemans/cli/templates/bench/environment/Dockerfile |
Installs iproute2. |
lib/lemans/agents/miniswen_installed.rb |
Enables jailed execution for installed Miniswen. |
CHANGELOG.md |
Records the release changes. |
Review details
Suppressed comments (4)
lib/miniswen/jail.rb:24
- This
unshareinvocation creates mount and network namespaces without a user namespace, so the exposedminiswen --jailoption requires root orCAP_SYS_ADMIN; a normal non-root invocation fails withEPERMbefore running any command. Either create and map a user namespace or make this privilege requirement explicit and validate it before starting the jail.
"unshare", "--net", "--mount", "--pid", "--fork", "--kill-child", "--mount-proc", "sh", "-c", SETUP, pgroup: true
lib/miniswen/jail.rb:13
- Replacing
/tmp(and similarly/rootor/run) hides any configured workdir below that mount. For example,Jail.new(workdir: "/tmp/project")starts with an empty/tmp, then everyexecfails whennsenter --wd=/tmp/projectcannot change directory. Preserve the workdir before overlaying scratch paths or reject/handle workdirs nested under them.
for dir in /tmp /run /root; do mkdir -p "/var/lib/miniswen$dir" && mount --bind "/var/lib/miniswen$dir" "$dir"; done
lib/miniswen/jail.rb:3
- This file only requires
miniswen/local, butcontainer_variablesreferencesAgent::EXEC_ENVand startup errors referenceInfrastructureError. A consumer that doesrequire "miniswen/jail"directly therefore gets aNameErroron the first command (or on a startup failure); the test helper masks this by loading the fullminiswenentrypoint first. Load the package entrypoint here before using those constants.
require "miniswen/local"
lib/miniswen/jail.rb:39
- Using the outer
/proc/1/environas the allowlist defeats the isolation when a credential was supplied to the container at startup: that variable name is included and its value fromENVis forwarded into the jailed shell. Keep an explicit allowlist of non-secret runtime variables instead of deriving it from PID 1.
[ ENV.to_h.merge(env.to_h).slice(*container_variables),
"nsenter", "--target", @holder.pid.to_s, "--net", "--mount", "--pid=/proc/#{@holder.pid}/ns/pid_for_children", "--wd=#{@workdir}",
- Files reviewed: 21/21 changed files
- Comments generated: 4
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
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.
The sandbox agent could use the harness's secrets: a DeepSeek model read
OPENROUTER_API_KEYfrom its environment and called OpenRouter with it for Perplexity searches, which the allowlist permits sincelemansitself talks to OpenRouter.Every agent command now runs jailed:
--jailruns every command in its own namespaces: none of the harness's environment, no network, read-only system, none of its files.miniswen-installedalways runs jailed.The jail is built on stock Linux tools (
unshare,nsenter,setpriv), the only semi-default pkg sandbox images need isiproute2to bring loopback up.Also: