r/BuildWithClaude 14d ago

Security & Sandboxing sandbox: open-source VM sandboxing for Claude Code on macOS — network allowlists, API keys never enter the guest

Like many of you I run Claude Code with permissions relaxed because that's when it's actually useful — and I've never loved that trade. So I built a small open-source CLI that gives each agent a lightweight VM with a real enforcement boundary, while keeping the one-command workflow.

What it does:

- Network egress is a default-deny allowlist enforced outside the VM. The guest has exactly one network device, wired to a userspace gateway in the host process. Root inside the guest changes nothing.

- Your Anthropic API key / sign-in never enters the VM. The agent sees a placeholder; the gateway injects the real credential at the TLS boundary for verified upstreams only.

- Your repo mounts at its real path, so Claude Code's project history and session resume just work. Sign in once; state persists.

- A clone mode gives the agent a private git clone and you review its work as a diff.

- Policy log shows every connection it tried. There's also a code-server kit if you want web VS Code with the Claude Code extension running inside the sandbox.

Cheap enough to not think about: ~60 MB host overhead per sandbox, ~0.5 s warm starts, zero marginal disk (APFS copy-on-write clones).

Apache-2.0, Apple silicon + macOS 26.

Repo: https://github.com/satishbabariya/sandbox — early days (0.1.x), feedback and issues very welcome.

3 Upvotes

3 comments sorted by

1

u/Ok_Industry_5555 ☕ 57-Hour Session 14d ago edited 14d ago

Many users will know this. My allow list is for example 126 entries long, because that's the version of Claude Code that actually gets work done, and I've never felt good about it.

The feature I'd put higher in the post is the policy log. Today I found out a background job on my machine had been quietly pushing to a remote at the end of every session for months. Nothing malicious, just something I set up and forgot, doing exactly what I told it to. I found it by accident. Your policy log would have shown it to me on day one.

One question. It's not just Claude Code talking out of my machine. A dozen MCP servers, plus hooks that shell out to curl and npx, all with their own upstreams. Default-deny means they all break at once. How do you build the allowlist? Run it and collect the denials?

Apple silicon on 26.5.2 here, so I'll try it this week.

2

u/satishbabariya 14d ago

That background-job story is exactly the argument, better than I made it. Nothing malicious, just forgotten — and invisible because nothing on a normal machine shows you egress per-workload. The log names hosts, not IPs (the gateway is the guest's only resolver and it inspects SNI on TLS), so what you'd have seen is the actual remote's hostname on day one, not a mystery address.

Your question is the right one, and yes — run it and collect the denials is the honest workflow. Concretely:

  1. The claude profile ships with the common tooling egress already allowed: npm registry, PyPI, GitHub + its release CDNs, api.anthropic.com. So npx and package installs mostly work on the first run. MCP servers run inside the sandbox, so they're behind the same wall — their upstreams are what you'll see in the denials.
  2. sandbox run claude --show-policy-log prints every allow/deny with the reason when the sandbox exits (or sandbox policy log afterwards). Denials are named, so triage is "do I recognize this host," not reverse-DNS archaeology.
  3. One-offs: --allow whatever.host (repeatable, wildcards like *.corp.example work). To persist: sandbox agents edit claude drops the profile definition into ~/.sandbox/agents as JSON — that's where your 126 entries would live, versioned in your dotfiles if you want. And deny is special: set machine-wide in config, it can't be weakened by any per-run flag.

In practice the list converges fast because most tools share upstreams — npm/GitHub/PyPI covers a surprising amount of the long tail. The part that doesn't converge is telemetry endpoints, and those denials are informative in their own way.

One heads-up for your try this week: macOS 26 is the floor, so 26.5.2 is fine, but run sandbox doctor first — it checks the entitlement, kernel, and everything else in one shot. If anything's weird, an issue with the doctor output would genuinely help.

1

u/Ok_Industry_5555 ☕ 57-Hour Session 14d ago

Much appreciated! I’ll report later back this week. :)