[codex] Add opt-in native Linux/macOS subprocess sandbox#7
Open
haowu1234 wants to merge 1 commit into
Open
Conversation
✅ Deploy Preview for exquisite-malabi-88852f ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
03ba2f8 to
80f08a2
Compare
Contributor
Author
c86b683 to
b8bc25a
Compare
b8bc25a to
2731c2f
Compare
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.

Closes #6.
Why
Inferoa should be able to run local coding-agent tools with a real OS boundary when users ask for it, while preserving today's default behavior for existing workflows. This PR adds that boundary as an opt-in capability: approvals still decide whether a tool should run, and the sandbox decides what the launched child process can touch.
The design goal is intentionally practical: normal development commands should keep working, but writes outside the workspace, protected metadata mutations, and restricted network access should fail in a way both users and the model can understand.
What changed
src/sandboxmodule built aroundPolicy -> Planner -> Backend -> ProcessRunner.sandbox.mode = off:offread_onlyworkspace_writeauto | macos_seatbelt | linux_bubblewrap | nonerestricted | enabledsandbox-execbwrap/dev/null,/dev/zero, random devices,/dev/fd, TTY/PTY, runtime/config read paths/dev,/proc, explicit writable binds, network namespace control--proc /procto a read-only/procbind on hosts that allow user namespaces but reject procfs mounting.workspace_write:.gitprotected by defaultgit_metadata_writecapability.inferoa/tmp,.inferoa/exports,.inferoa/artifacts,.inferoa/evidence,.inferoa/cache, and.inferoa/sandboxare writable artifact paths.inferoacontrol-plane paths and unknown.inferoa/*paths remain protected.codex,.claude, and.agentsremain protectedapply_patch, Git/search/code-intelligence helpers, and autoresearch harness execution./sandboxTUI commands and status display while keeping/accessapproval policy separate./sandbox statuseffective writable root display so users see the actual workspace root andos.tmpdir()path instead of ambiguoustmpwording.outside_workspace_writeprotected_metadata_writegit_metadata_requires_capabilitynetwork_restrictedplatform_baseline_deniedsandboxare no longer mislabeled as sandbox blocks..inferoachild paths covered by a read-only parent no longer generate bubblewrap setup-time mkdir failures.network_restrictedsandbox explanation when the command has clear network intent.upstream/mainat944f850and kept the PR branch conflict-free.Validation
Automated validation on macOS after rebasing onto
upstream/main:npx -y -p node@24 -p npm@11 npm run check npx -y -p node@24 -p npm@11 npm testResult:
286/286tests passed, including the native macOS Seatbelt probe.Automated validation on a TencentOS Server 3.2 Linux remote development machine with
bubblewrap 0.4.0:npx -y -p node@24 -p npm@11 -c 'node -v; npm -v; npm run check; npm test'Result: Node
v24.16.0, npm11.16.0, and286/286tests passed, including the native Linux bubblewrap probe. This host rejects--proc /procinside bwrap withOperation not permitted, so the backend exercised the read-only/procbind fallback and still passed the sandbox probe.The test suite now includes:
/sandbox statuseffective writable roots coverageNative OS probe coverage included:
/dev/null,mktemp, shell piping, and basic process plumbing succeed.inferoaartifact writes succeed.gitwrites are denied by default.inferoacontrol-plane and unknown writes are deniednetwork_restrictedInteractive strict negative validation was also run in
workspace_writewith network restricted. Each negative command was executed independently so failures were not swallowed by shell||handling.Result: PASS, with follow-up UX fixes added for network explanation and effective tmp display.
Observed policy outcomes:
$HOME/.inferoa-sandbox-negative-query-deniedoutside_workspace_write; target absent.git/inferoa-sandbox-negative-query-deniedgit_metadata_requires_capability; target absent.inferoa/config.yamlprotected_metadata_write.inferoa/secrets.jsonprotected_metadata_write.inferoa/*pathprotected_metadata_write.inferoa/pluginsprotected_metadata_write$HOMEnode net.connect(1.1.1.1:80)with restricted networknetwork_restrictedgit branch create + deleteTop-level workspace checks were also run from the orchestration repo:
The parent workspace was already dirty/untracked outside this contribution worktree, and
third_party/vllm/rustremains an uninitialized nested submodule. Those states are unrelated to this PR.Notes for reviewers
The sandbox is deliberately opt-in.
sandbox.mode = offpreserves current behavior. This PR sandboxes tool subprocesses, not the already-running Inferoa Node process. Domain-level network allowlists, Docker/Podman backends, proxy routing, and whole-agent sandboxing are left for future work.