How Secure Is the Claude Code Sandbox on the Mac?
A Look Under the Hood of Claude Code and Cowork
AI agents execute commands on your machine — but how well do the sandboxes of Claude Code and Cowork actually protect you? Both promise isolation, yet rely on entirely different mechanisms. I didn’t just read the documentation — I examined both systems from the inside using standard Linux tools. The result: the isolation is real, verifiable, and surprisingly well thought out.
“If Claude decides to delete all my files: no big deal — but only inside an isolated VM.”
Anyone who uses Claude Code in the terminal with default settings knows the drill: many commands require approval before Claude Code executes them. You constantly have to weigh whether a given command is safe or not.
“Allow this? Allow once? Allow always?”
You keep checking: is this harmless, or could this command cause problems? Cognitive load from reading command lines.
There are essentially two extremes: either you review every single permission request yourself, or you use the --dangerously-skip-permissions option, which allows everything. In between, there are many gradations. You can define your permissions with fine granularity, but that’s almost as much effort.
How nice would it be if you could simply allow everything while still being certain that nothing unwanted happens on your machine. Then agentic coding could proceed unhindered and you’d get results fast.
That’s exactly what an isolated system promises — one that runs shielded from your actual computer. Such an isolated system reduces the blast radius — the maximum damage a misguided command can cause — immensely. If something goes wrong, you simply restart and return to the last stable state. There are many ways to implement this.
One of them is the /sandbox command built into Claude Code. It activates a sandbox that restricts Claude Code at the OS level — file access and networking. You can let commands run automatically without confirming each one, because the sandbox limits what can happen. But how secure is it really?
And then there’s Cowork in the desktop version of the Claude app. Cowork is aimed more at knowledge workers than developers. It can access folders, create and modify files, install packages — all autonomously. At first glance, it’s not obvious how the protection works. There’s no /sandbox command you’d need to activate. The isolation happens in the background.
I was curious about both: how does the sandbox work in Claude Code? And how does Cowork protect me from unwanted changes on my machine?
I didn’t want to rely on the documentation alone — instead, I examined both systems from the inside. Here’s what I found.
Two Products, Two Audiences, Two Security Models
Before I dive into the technical details, an important distinction:
Claude Code is a terminal tool for developers. It executes commands on your machine — in the same context where you work. The sandbox must be manually activated (/sandbox), making it opt-in. That makes sense: developers need as few restrictions as possible to be productive. They want to run commands that a restrictive sandbox would block. But with great power comes great responsibility. You need to understand what you’re approving.
Cowork is part of the Claude Desktop app and is aimed at users who don’t want to deal with the command line. When someone asks Claude to create an Excel spreadsheet from five PDFs, they expect a result — not a discussion about file permissions. Cowork therefore needs to provide stronger protection, without requiring the user to configure anything.
The result: two different isolation models for two different risk profiles.
Let’s get into the details.
Cowork: A Linux Inside Your Mac
Cowork launches a lightweight Linux VM via Apple’s Virtualization.framework. Not a container, but a real virtual machine with its own kernel.
What does the VM say about itself?
$ cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.5 LTS"
$ uname -r
6.8.0-94-generic
$ uname -m
aarch64
$ nproc
4
$ free -h
total used free
Mem: 3.8Gi 564Mi 1.8Gi
Swap: 0B 0B 0B
$ df -h /
Filesystem Size Used Avail Use%
/dev/nvme0n1p1 9.6G 7.2G 2.4G 75%
Ubuntu 22.04 on ARM64, 4 cores, 3.8 GB RAM, a 10 GB disk. No swap. Lean enough for document processing and scripts, but not meant for machine learning training.
On the macOS host, the VM files live at ~/Library/Application Support/Claude/vm_bundles/claudevm.bundle/. The root image (rootfs.img) is 10 GB as a sparse file but only occupies about 7.5 GB on disk.
Alongside it sits a compressed backup (rootfs.img.zst, ~2 GB) and a few configuration files: efivars.fd, macAddress, machineIdentifier.
How Three Layers Work Together to Secure the Isolation
The VM alone would already be a solid boundary. But Anthropic stacks three layers on top of each other.
Layer 1: The VM
Apple’s Virtualization.framework provides hardware isolation. The guest has its own kernel. Even an rm -rf / inside the VM leaves the host untouched.
Layer 2: bubblewrap + seccomp
Inside the VM, Claude doesn’t run directly — first comes bubblewrap (short: bwrap). Bubblewrap is a sandboxing tool that uses Linux namespaces to isolate processes from each other — similar to what containers do, but more lightweight.
It restricts what a process can see and do: which files, which network interfaces, which other processes.
In the Cowork VM, bubblewrap is PID 1 — the very first process:
$ cat /proc/1/status | head -2
Name: bwrap
State: S (sleeping)
The bwrap command line (readable via /proc/1/cmdline) shows the key restrictions at a glance:
--unshare-net— separate network namespace, no direct network access--unshare-pid— separate PID namespace, other processes invisible--ro-bind / /— root filesystem mounted read-only--die-with-parent— if the parent process dies, the sandbox dies with it--tmpfs /etc/ssh/ssh_config.d— SSH configuration overlaid with an empty tmpfs
Additionally, a seccomp filter is loaded. Seccomp (Secure Computing Mode) is a Linux kernel mechanism that determines which system calls a process is allowed to make. System calls are the interface between a program and the operating system — opening files, establishing network connections, starting processes.
A seccomp filter can selectively block individual system calls, drastically limiting a process’s radius of action.
$ grep Seccomp /proc/self/status
Seccomp: 2
Seccomp_filters: 2
Seccomp: 2 means filter mode — there’s an active allowlist for permitted syscalls. The filter file is called unix-block.bpf and is loaded via a dedicated binary (apply-seccomp).
Layer 3: Network Isolation
No process in the sandbox has direct internet access. All traffic goes through a local proxy:
$ env | grep HTTP_PROXY
HTTP_PROXY=http://localhost:3128
$ env | grep ALL_PROXY
ALL_PROXY=socks5h://localhost:1080
The proxy runs via socat, which tunnels TCP connections into Unix sockets that lead out of the VM. On the host side, an allowlist decides which domains may pass through.
I tested it:
$ curl -s -o /dev/null -w "%{http_code}" https://registry.npmjs.org
200
$ curl -s -o /dev/null -w "%{http_code}" https://pypi.org
200
$ curl -sv https://evil-exfiltration-test.example.org 2>&1 | grep "HTTP/1.1"
< HTTP/1.1 403 Forbidden
$ curl -sv https://evil-exfiltration-test.example.org 2>&1 | grep "X-Proxy"
< X-Proxy-Error: blocked-by-allowlist
npm and PyPI get through. Everything else receives a 403 Forbidden with the header X-Proxy-Error: blocked-by-allowlist. Direct DNS lookups also fail:
$ nslookup google.com
socket(): Operation not permitted
;; no servers could be reached
This is consistent: even if a prompt injection attack were to trick Claude into sending data to an external server — the proxy would block it.
Which Files Does the VM See?
Files enter the VM via VirtioFS — a filesystem protocol designed specifically for communication between a VM and its host. Instead of simulating real hardware, host and guest cooperate deliberately (paravirtualization). This makes file access fast and low-overhead.
$ mount | grep virtiofs
/mnt/.virtiofs-root/shared/Work/.../Marketing on
/sessions/elegant-adoring-brown/mnt/Marketing type fuse (rw,...)
Only the folder I selected in the Desktop app is mounted. Not my home directory, not my Desktop, not my Downloads — just the one folder I explicitly shared.
Plugins and Skills are additionally mounted via bindfs. Bindfs is a FUSE filesystem that remounts an existing folder at a different location — similar to a symlink, but with the ability to change permissions. This way, Skills can be mounted read-only even though they’re writable on the host. Uploads also land in a separate, read-only mount.
One detail reveals that the VM serves multiple conversations simultaneously: the /sessions/ directory contains different sessions side by side:
$ ls -la /sessions/
drwxr-x--- elegant-adoring-brown elegant-adoring-brown ...
drwxr-x--- nobody nogroup awesome-epic-mccarthy
drwxr-x--- nobody nogroup dazzling-vibrant-carson
Each session gets its own Linux user with its own UID. My user is called elegant-adoring-brown (uid 1005). The other sessions are listed under nobody — I can’t read their files.
How Does Claude Code Protect Without a VM?
Claude Code in the terminal uses a different approach on macOS: Apple’s Seatbelt (also known as sandbox-exec). Instead of a VM, a dynamically generated sandbox profile restricts the process at the OS level. Important: the sandbox must be manually activated with /sandbox — without this step, Claude Code runs without OS-level isolation.
The profile starts with (deny default) — everything is forbidden unless explicitly allowed. The sandbox runtime is open source and available on GitHub. I downloaded the npm package @anthropic-ai/sandbox-runtime and analyzed the macos-sandbox-utils.js:
59 sysctl entries are made readable (hardware info like CPU count, memory size)
14 Mach IPC services on the whitelist (Fonts, Logging, Security Server)
Mandatory denies for
.env,.ssh,.aws,.git/hooks,.git/config— even when the working directory has write accessMove blocking:
file-write-renameandfile-write-unlinkare blocked for protected paths, preventing circumvention of the denies viamv
The network isolation works the same way as with Cowork: all traffic goes through the same proxy with an allowlist. The difference: with Seatbelt, this happens at the process level (same kernel); with Cowork, at the VM level (separate kernel).
Why Two Models?
Claude Code is aimed at developers who need fast feedback in the terminal. The Seatbelt overhead is in the low single-digit millisecond range — I measured it on the host, no perceptible difference from a command without sandbox. Developers can selectively activate the sandbox when they want to give an agent more autonomy without having to approve every command.
Cowork gives Claude significantly more autonomy: it runs longer, creates files independently, installs packages. And it’s aimed at users who can’t assess (and don’t need to assess) which commands are being executed at the operating system level. The potential damage from an agent with local file access, code generation, and network egress is greater — and users are less able to evaluate it. Full VM isolation is appropriate here.
What I Take Away From This
The isolation is real. Not just on paper, but verifiable.
Three things convinced me in particular:
First, the proxy allowlist with the explicit X-Proxy-Error: blocked-by-allowlist header. This isn’t a silent error message but a deliberate architectural decision. You can immediately see why a connection fails.
Second, the layering. The VM alone would be good. With bubblewrap and seccomp, it gets better. All three together make it significantly harder to break out of the sandbox. An exploit would have to simultaneously bypass the seccomp filter, escape the bwrap namespace, and then break out of the VM — on a system with no direct network access.
Third, the transparency. The sandbox runtime is open source. I downloaded the macos-sandbox-utils.js code — the 59 sysctl entries, the 14 Mach services, and the mandatory denies for .env, .ssh, and .aws are all there in black and white. The Seatbelt profile is dynamically generated, but the generating code is inspectable. The VM architecture can be examined from the inside. You don’t have to take anyone’s word for it — you can look for yourself.
If you want to look for yourself: the sandbox runtime is on GitHub. An npm pack and a look at macos-sandbox-utils.js is all it takes to understand the Seatbelt profile.
What You Can Do Now
If you’re using Claude Code and haven’t tried the sandbox yet: start a session and type /sandbox. That alone significantly reduces the effort of approving commands one by one. For everyday use, that’s often enough.
If you want to go deeper:
Inspect the sandbox runtime:
npm pack @anthropic-ai/sandbox-runtime, unpack, readmacos-sandbox-utils.js. There you’ll see exactly what’s allowed and what’s blocked.Examine Cowork from the inside: Launch Cowork and ask it to run
cat /proc/1/cmdline | tr '\0' '\n'. The bubblewrap flags reveal the isolation in detail.Test the network: A
curl https://evil-exfiltration-test.example.orginside the sandbox immediately shows you whether the allowlist is working.
What’s Next?
The current state is clear. But one question remains: will it stay this way? Claude Code and Cowork already share the agentic architecture — and there are concrete signals that the security models are converging as well:
Docker is delivering MicroVM sandboxes with
docker-model-runner, specifically designed for AI agents.Apple is bringing its own Containerization framework with macOS 26 — native container support on the Mac for the first time.
Anthropic documents DevContainers as the official path toward stronger isolation in Claude Code.
Three players, three approaches, one goal: agents should be able to do more without being able to cause more damage. In the next article, I’ll examine the pros and cons of each path — and why I consider one of them the most likely.
If you want to be notified when the next article is published:
Subscribe to my Substack — free, no spam, just substance.
Sources
Inside Claude Cowork (Pedro José Pereira Vieito) — Reverse engineering analysis of the VM architecture


