Sandboxing Coding Agents
I've been playing with coding agents recently, with a bit of success. However, I've found it really painful to have to continually answer the agent's requests for permission to carry-out various operations: "Can I run make?", "Can I grep the project directory?", and so on, ad infinitum. After all, I want these things to run independently while I do other work, not continually interrupt my flow.
I see that Claude has recently introduced something they're calling "auto-mode" that might be able to help with this, but prior to that, the primary alternative seemed to be to run Claude with the --dangerously-skip-permissions flag, which seemed, well, dangerous.
The obvious move, it seemed to me, was to run the agent in "dangerous" mode inside some kind of a sandbox with restricted access to the outside world. It seems a lot of people are doing this: I found a number of posts on the topic that used containers, or virtual machines to try to accomplish this. I started with ndbecker's bub.sh, which uses bubblewrap. bubblewrap employs the same Linux facilities that underpin containers (cgroups, mount namespaces &c) to run processes with limited access to the host machine.
The missing piece, however, was locking-down network access. The posts I read were generally concerned with protecting the host on which the agent ran, not controlling its network activities. bubblewrap offers an --unshare-net flag, but that turns off all network access; the sandboxed process is left with nothing other than the loopback interface. Taiki Sakamoto's post "Trying out bubblewrap used in Claude Code's Sandbox Runtime and exploring its network restriction mechanism" demonstrates a clever workaround:
- stand-up a whitelisting proxy on the host machine; I chose squid with an allowlist
- use
socatto create a relay between a Unix domain socket and the listening proxy instance - mount that socket into the sandbox's filesystem
- use
socatin the sandbox to create a relay between a listening socket inside the sandbox and the Unix domain socket; anyone who writes to that listening socket in the sandbox will have their request eventually wind-up at squid on the host - set the
http_proxy&https_proxyenvironment variables in the sandbox to that listening socket to make sure everyone does so
And that's it: I was able to get Claude Code up & running for Rust development with both filesystem & network access locked-down. I posted the proof of concept on Github. I'll probably wind-up renaming it, since I just realized there's already an Emacs package by the same name.
03/31/26 11:37