b0ce83a937
The SDK's built-in Bash tool ran commands as a bare subprocess with only current_dir set — no OS boundary. On a server that let an agent shell read /etc/shadow, cd /, write anywhere the process uid could, and reach the network; the phase-1 path validation only guards the file tools, not bash. (The SDK's SandboxSettings is dead config: Agent::new never reads it.) Replace it with SandboxedBashTool — same name and input schema, registered via custom_tools so it overrides the built-in by name — that confines the command with bubblewrap, gated by permission mode: - Default / AcceptEdits (review modes): run inside a bwrap namespace with the system mounted read-only, the session sandbox dir bind-mounted rw at its real path and made the cwd, /etc //root //home and all other host paths absent, and --unshare-all (network included). Filesystem escape and network egress are blocked by the kernel, not by convention. - FullAccess (explicitly dangerous): unconfined, same as before, but every command is audit-logged with a warning. Fail-closed: in a review mode, if bwrap is unavailable the command is refused rather than silently run unconfined — no fabricated boundary. Verified end-to-end in tests/agent_bash_sandbox.rs by invoking the tool: under Default mode `cat /etc/passwd` sees no host passwd, `ls /` exposes no etc//root//home, a write to /etc/cron.d/x fails (and the host file is never created), and the network is unreachable; in-sandbox work succeeds and lands in the real session dir; FullAccess can see the host. bwrap 0.11.2 confirmed functional on this host (root, CAP_SYS_ADMIN, user namespaces enabled). Phase-1 suites stay green.