Skip to content

How to run Claude Code in a sandbox?

Store your Anthropic key on the host, make a sandbox that reaches only Anthropic and npm, and give Claude Code a task:

Terminal window
printf '%s' "$ANTHROPIC_API_KEY" | shard secret set --destination api.anthropic.com ANTHROPIC_API_KEY
shard policy create --allow api.anthropic.com --allow registry.npmjs.org --deny any claude
shard create --name claude --memory 2GiB --user node --workdir /home/node \
--secret ANTHROPIC_API_KEY --policy claude \
--env CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 node:22
shard exec --user root claude npm install -g @anthropic-ai/claude-code
shard exec claude claude -p --dangerously-skip-permissions \
"Write fizzbuzz.js that prints FizzBuzz from 1 to 15, then run it with node"
shard cp claude:/home/node/fizzbuzz.js ./fizzbuzz.js

Claude Code writes the file, runs it, and prints a summary. The last command copies the file out to your machine.

--dangerously-skip-permissions lets Claude Code run any command without asking. On your laptop that is a risk. In the sandbox, the worst it can do is break the sandbox:

  • It sees no key. The sandbox holds mock-ANTHROPIC_API_KEY. The host puts the real key into each HTTPS request to api.anthropic.com, outside the sandbox. See Give a sandbox an API key.
  • It reaches two hosts. The policy allows Anthropic’s API and the npm registry, and denies the rest. shard policy logs claude shows each request it made.
  • It touches no file of yours. It sees the image’s files and what you copy in.

The sandbox does not limit what Claude Code does with what it can reach. It spends your Anthropic key on every request, and it can send any file you copy in to an allowed host. Copy in only what the task needs.

Claude Code refuses --dangerously-skip-permissions as root, so the sandbox runs commands as the image’s node user. The install runs as root because it writes to /usr/local.

CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 turns off telemetry and error reports, so the policy needs no host for them.

Copy a project in, let Claude Code change it, and copy the result back:

Terminal window
shard cp ./myapp claude:/home/node/
shard exec --workdir /home/node/myapp claude claude -p --dangerously-skip-permissions "Fix the failing tests"
shard cp claude:/home/node/myapp ./myapp-fixed

If the agent needs more hosts, such as github.com or pypi.org, add them to the policy. Run shard policy create again with the same name, and the running sandbox gets the new rules at once. The new rules replace the old ones, so repeat every --allow you still need:

Terminal window
shard policy create --allow api.anthropic.com --allow registry.npmjs.org --allow github.com --deny any claude
Terminal window
shard shell claude
claude

On the first start, Claude Code asks whether to use the API key it found in the environment. Say yes: the key it found is the placeholder.

Fork the sandbox once Claude Code is installed, and give each copy a different prompt:

Terminal window
shard fork --name claude-b claude
shard exec claude claude -p --dangerously-skip-permissions "Solve it with a loop"
shard exec claude-b claude -p --dangerously-skip-permissions "Solve it with recursion"

fork works on gVisor, Firecracker, and vz on Apple silicon with macOS 14 or later. Sysbox and runc refuse it. See Fork a sandbox to try two paths.

Terminal window
shard remove --force claude claude-b
shard policy remove claude