feat(core,cli): M3.5 — sandbox subsystem (macOS sandbox-exec + Linux bwrap)#13
Merged
Conversation
…bwrap)
What ships
----------
- packages/core/src/sandbox/profile.ts
· detectPlatform() → 'macos' | 'linux' | 'unsupported'
· buildMacOsProfile(config, cwd) — generates SBPL text:
- (deny default) baseline
- allow system reads (/usr /System /Library /private/etc /dev /bin ...)
- allow allowRead paths (with ~ expansion + SBPL escaping)
- allow allowWrite paths
- deny denyRead / denyWrite paths (appended after allows so deny wins)
- net allow* by default; allowUnixSockets opt-in
· buildLinuxBwrapArgs(config, cwd) — generates bwrap argv:
- --ro-bind-try for system dirs
- --bind for cwd
- --unshare-pid --unshare-ipc --unshare-uts always
- --unshare-net iff allowedDomains is explicit empty array
- packages/core/src/sandbox/index.ts
· wrapBashCommand({ userCommand, cwd, config }) → { command, args }
Returns sandbox-exec / bwrap wrapping, or /bin/sh unwrapped when:
· config.enabled is false
· platform unsupported (Windows)
· userCommand starts with an excludedCommands entry
- packages/core/src/tools/bash.ts
· Reads ctx.sandboxConfig (typed in ToolContext)
· Wraps every Bash invocation under platform sandbox if configured
- packages/core/src/agent.ts
· runAgent now accepts opts.sandboxConfig; plumbed into ToolContext
- apps/cli/src/repl.ts
· Passes settings.sandbox to runAgent — fully wired end-to-end
Tests (17 new, 316 total / 308 + 8 skipped)
-------------------------------------------
- sandbox/profile.test.ts (11): platform detect, disabled→empty, system reads,
allow/deny ordering, SBPL escaping, unix-socket opt-in, bwrap binds + cwd
rw + unshares + conditional --unshare-net
- sandbox/index.test.ts (6): disabled passthrough, no-config passthrough,
excludedCommands bypass (prefix + exact), platform-conditional wrapping
Verified
--------
pnpm typecheck → green
pnpm test → 308 passed / 8 skipped / 0 failed (was 297)
pnpm format:check → conformant
Deferred (per plan §6 / docs/design/sandbox-plan-worktree.md)
--------------
- Adversarial e2e test suite (fs-traverse / net-exfil / privilege-escalation
/ sandbox-escape fuzzing) — M3.5-attack-suite separate PR
- Userspace DNS proxy for fine-grained allowedDomains enforcement
- docs/security-model.md (threat model + defense coverage)
What this ships safely
----------------------
The sandbox wrapper is opt-in via settings.sandbox.enabled. Default deepcode
behavior (no settings.sandbox) is unchanged — Bash still runs unwrapped on
/bin/sh. Users who enable sandbox get default-deny SBPL on macOS and bwrap on
Linux. The hardening surface (which paths/domains to allow/deny) is theirs to
tune; we don't ship pre-canned policies.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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
wrapBashCommand()opt-in viasettings.sandbox.enabled; honorsexcludedCommandsallowlistDeferred
Release notes
release-notes:featureCo-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com