Claude Code Sandbox: Running Unattended Agents Safely
Eli Mernit9 min read
A Claude Code sandbox limits what the agent can read, write and reach while it works. For everyday use, Claude Code's built-in sandboxed Bash tool is enough. To run unattended with --dangerously-skip-permissions, Anthropic's docs say to put the whole Claude Code process inside a container or VM, run it as a non-root user, and restrict outbound network access.
This guide covers each option Anthropic documents, then walks through the unattended setup on a remote VM, including the root-user error that stops most first attempts.
# Store the API key so that only api.anthropic.com can receive it
beam secret create ANTHROPIC_API_KEY "$ANTHROPIC_API_KEY" --host api.anthropic.com
# Create a VM with the secret bound, then upload the repo to /workspace
beam vm new claude-box --secret ANTHROPIC_API_KEY
beam vm sync claude-box ./my-project
# Claude Code refuses to skip permissions as root, so add a regular user
beam vm exec claude-box -- sh -c 'useradd -m agent && chown -R agent:agent /workspace'
beam vm exec claude-box -- runuser -u agent -- bash -c 'cd ~ && curl -fsSL https://claude.ai/install.sh | bash'
# Allow only the hosts this run needs, and save a restore point
beam vm network claude-box --allow api.anthropic.com --allow github.com
beam vm snapshot create claude-box --name before-run
# Run the agent headless with prompts off
beam vm exec --cwd /workspace claude-box -- sh -c \
'runuser -u agent -- env HOME=/home/agent ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
/home/agent/.local/bin/claude -p "Run the test suite and fix the failing tests" \
--dangerously-skip-permissions'What a Claude Code sandbox does
A sandbox sets the blast radius for anything Claude does without asking you. Permission modes decide whether a tool call runs. Isolation decides what that call can touch once it runs. Anthropic's docs treat them as separate layers, and when prompts are off the isolation layer is all that protects your machine.
The term covers several setups. Anthropic's sandbox environments guide ranks them like this:
- Sandboxed Bash tool. Built into Claude Code. It restricts the filesystem and network access of the shell commands Claude runs, plus their child processes. You turn it on with
/sandbox. It works on macOS, Linux and WSL2, but not on native Windows. - Sandbox runtime. The
@anthropic-ai/sandbox-runtimepackage wraps the whole Claude Code process, including file tools, hooks and MCP servers, with the same Seatbelt or bubblewrap isolation. Anthropic labels it a beta research preview. - Dev container. Claude Code runs inside a Docker container that your editor manages. Anthropic publishes a reference container with a default-deny firewall.
- Custom container or VM. Any container image or virtual machine with your own network policy. Anthropic's docs call a dedicated VM the strongest separation, with its own kernel.
- Cloud sessions. Claude Code on the web runs each session in an Anthropic-managed VM. It needs a Claude subscription.
One detail matters more than the rest. The sandboxed Bash tool doesn't cover Read, Edit, MCP servers or hooks, which run in the main Claude Code process on your host. Anthropic's docs say it isn't enough on its own for fully unattended runs.
Is --dangerously-skip-permissions safe?
It's safe only inside an isolation boundary you trust, and only if you accept what the agent can still reach from there. The flag switches Claude Code into bypassPermissions mode, so tool calls run without a prompt. Anthropic's warning is direct: use the mode only in isolated environments, such as containers, VMs or dev containers without internet access.
Three limits stay in place even with the flag on:
- Deny rules still apply. A deny rule in your settings blocks a tool call in every mode. Allow rules do nothing in bypass mode.
- Some actions always prompt or fail. Anthropic lists a few actions that no mode approves on its own, such as dangerous
rmcommands on critical paths. In aclaude -prun, those calls get denied instead of prompting. - Prompt injection isn't covered. Bypass mode offers no protection against a malicious README or web page steering the agent. Isolation limits the damage. It doesn't stop the attempt.
If you want fewer prompts without giving up every check, auto mode (--permission-mode auto) sends each action through a classifier first. Anthropic recommends it over bypass mode for most hands-off work, and says an isolation boundary still adds defense in depth.
Why Claude Code refuses to run as root
On Linux and macOS, Claude Code won't start in bypass mode as root or under sudo. It exits with this error:
--dangerously-skip-permissions cannot be used with root/sudo privileges for security reasonsThis trips up most cloud setups, because many containers and VMs hand you a root shell. Beam VMs are one of them: beam vm ssh and beam vm exec connect as root. The fix is the one Anthropic gives for containers: create a regular user and run Claude Code as that user. The quickstart above does this with useradd and runuser, and installs Claude Code into the new user's home with Anthropic's native installer.
The same root check explains why beam vm prompt doesn't skip permissions. Beam VM images include the Claude Code and Codex CLIs, and beam vm prompt devbox "…" --agent claude runs claude -p with your prompt and keeps a durable session log. It doesn't pass a permission mode, so Claude Code starts in Manual mode, and any call that needs approval gets denied. Use beam vm prompt for read-only or pre-approved work, such as "explain how to run this project's tests". For edits and shell commands, add allow rules in the VM's Claude Code settings, or run the command shown above as a non-root user.
How to run Claude Code unattended in an isolated VM
Running unattended safely takes five things: a separate machine, a non-root user, a scoped credential, an egress allowlist, and a restore point. A remote VM supplies the first one outright and makes the other four short commands. The quickstart at the top runs all five in order. Here's what each step does and what it protects against.
Keep the API key out of the agent's reach
When you bind a Beam secret to a VM, the guest sees a placeholder that starts with beam_secret_, not the real value. Beam's worker swaps in the real value only in HTTPS request headers sent to the hosts you approved. It also scrubs the literal value from responses. Claude Code sends your Anthropic API key as an HTTPS header, so --host api.anthropic.com means even an agent that prints its environment and posts it somewhere leaks only the placeholder.
Two limits from Beam's secrets docs: substitution happens only in headers over HTTPS on port 443, and certificate-pinned clients can't use it.
Limit where the agent can connect
beam vm network claude-box --allow HOST turns the VM's egress into an allowlist of up to 64 hostnames, wildcard domains, IPs or CIDRs. Rules persist across restarts and take effect without a reboot. Under an allowlist, UDP and ICMP are blocked except DNS.
Claude Code needs api.anthropic.com for model calls. If you sign in with a Claude account instead of an API key, also allow claude.ai and platform.claude.com. Add only what the task needs beyond that, for example github.com to clone and push, or registry.npmjs.org and pypi.org to install packages. Claude Code also sends optional telemetry to Datadog hosts. Set CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 rather than allowing them.
Run the installer before you apply the allowlist, since it downloads from Anthropic's hosts. If the agent needs nothing but the model, beam vm network claude-box --block leaves only your approved credential hosts reachable.
Save a restore point before risky runs
beam vm snapshot create saves the VM's root disk as a reusable restore point. If a run deletes the wrong directory or wrecks the environment, start a fresh VM from it with beam vm fork SNAPSHOT_ID claude-box-2. You can also fork a live VM, for example beam vm fork claude-box attempt-b, to try two approaches side by side. Each fork gets its own disk, ID and URLs. Snapshots and forks copy the filesystem only. Running processes and RAM are kept only by beam vm pause and beam vm resume.
Run long jobs in the background
A foreground beam vm exec streams output and returns the exit code. For a long job, add --detach --json and follow it with beam vm logs claude-box --pid PID -f. New VMs have no idle timeout by default. If you set one with --ttl, detached work doesn't keep the VM awake once your CLI exits, so leave the timeout off for unattended runs. To stop paying between runs, beam vm pause claude-box releases compute and keeps memory, and beam vm stop keeps only the disk.
Choosing a sandbox for Claude Code
Pick by where the code runs and how much you trust it. On your own machine with code you trust, the built-in Bash sandbox in auto-allow mode removes most prompts with almost no setup. For unattended runs on your laptop, the dev container or the sandbox runtime puts the whole process behind a boundary. For untrusted repositories, many parallel agents, or runs that last hours, Anthropic's guidance points to a dedicated VM or a cloud session.
| Option | What it isolates | Where it runs | Fit for skip-permissions | Egress control |
|---|---|---|---|---|
| Sandboxed Bash tool | Shell commands only | Your machine | No, file tools and MCP run outside | Domain allowlist in settings |
| Sandbox runtime | Whole Claude Code process | Your machine | Yes, beta | Denies network until you allow domains |
| Dev container | Whole dev environment | Local Docker or Codespaces | Yes, as non-root | Reference firewall script |
| Cloud sessions | Full OS in an Anthropic VM | Anthropic | Settings can't turn on bypass mode | Default allowlist proxy |
| Beam VM | Full OS in a microVM with its own kernel | Beam cloud | Yes, as non-root | Hostname and CIDR allowlist, brokered secrets |
Where the local options win: they're free, they see your files directly, and there's no upload step. Anthropic's cloud sessions need no setup if you already pay for Claude. A Beam VM makes sense when you want a machine that keeps its state between runs, can be forked for parallel attempts, and bills per second only while it runs. At list rates, the default size of 4 vCPUs and 8 GiB costs $0.28 an hour on the Performance tier, the default for new accounts, or $0.088 an hour on the Shared tier. A paused or stopped VM accrues no compute charges.
For background on why a microVM boundary is stronger than a container, see what a microVM is. If you're comparing hosted options, our guide to Docker Sandbox alternatives covers E2B, Daytona and Modal, and the stateful sandbox comparison covers which state each provider keeps. Teams running several agents at once can start from the coding agents use case and the virtual machines overview.
FAQ
Does Claude Code have a built-in sandbox?
Yes. The sandboxed Bash tool restricts the filesystem and network access of shell commands Claude runs, and you configure it with /sandbox. It runs on macOS, Linux and WSL2. It doesn't cover file tools, MCP servers or hooks, so it isn't enough on its own for unattended runs.
How do I run Claude Code in Docker?
Use Anthropic's dev container, or any container image with Claude Code installed, and run it as a non-root user. Anthropic's reference container adds a firewall script that blocks unapproved egress, which is what makes --dangerously-skip-permissions reasonable inside it. Credentials stored in ~/.claude inside the container are still readable by the agent.
Why does --dangerously-skip-permissions fail as root?
Claude Code refuses bypass mode when it runs as root or under sudo on Linux and macOS. Create a regular user and start Claude Code as that user. In a Beam VM, useradd plus runuser -u does it, as in the example at the top of this page.
Can Claude Code still leak data from a sandbox?
Yes, if the sandbox allows network egress to hosts the agent can write to. Anthropic's docs say any approach with open egress can leak data the agent can read. Restrict egress to the hosts the task needs, and keep real credentials out of the guest with a proxy that injects them only for approved hosts.
Is auto mode safer than skipping permissions?
Auto mode keeps a classifier between Claude and each action, so it blocks some risky calls that bypass mode would run. It's still a per-action check, not an isolation boundary. For unattended work, Anthropic suggests auto mode plus a container or VM.
Can I use a Claude subscription instead of an API key in a remote VM?
Yes. Run claude setup-token locally to create a long-lived token, and set it in the VM as CLAUDE_CODE_OAUTH_TOKEN. Anthropic's network requirements list claude.ai and platform.claude.com for account sign-in and token refresh, so add them to the allowlist next to api.anthropic.com.
Ready to give Claude Code a machine of its own? Create a Beam account and start a VM with beam vm new claude-box.
