Guide

Setting Up a Sandbox Environment for Your AI Coding Agent

An AI coding agent runs commands and edits files with your permissions. The best sandbox setup gives it room to work and a hard wall around everything else.

Quick Answer

To set up a sandbox for an AI coding agent, pick a real isolation boundary rather than a verbal instruction: Docker Sandboxes (the sbx CLI) gives each agent its own disposable microVM, and macOS ships a built-in alternative called sandbox-exec that enforces file and process rules at the kernel level with no virtualization overhead. Either way, set a default-deny network policy and keep secrets out of the sandboxed filesystem entirely, injecting them into a command only when it runs.

Why a coding agent needs a sandbox at all

An AI coding agent reads files, writes files and runs shell commands on your behalf. It does not ask the operating system for special permission first, it just acts with whatever access you have. A hallucinated package name can pull a typosquatted dependency from a public registry, and a bad `rm` suggestion that you approve without reading closely can take out more than the agent intended.

A sandbox setup does not try to make the agent behave better. It limits what happens when it does not. The agent gets enough room to install packages, compile code and run your test suite, and nothing outside that room is reachable: not your SSH keys, not your other projects, not your home directory.

The two realistic choices on a Mac are a microVM-based tool like Docker Sandboxes, which trades a little startup time for a near-complete boundary, and the kernel-level sandbox-exec, which has effectively no overhead but asks you to write the rules yourself.

  • Agents act with the permissions of whoever started them, by default.
  • A sandbox limits the damage from a bad command, not the odds of one happening.
  • MicroVM tools cost a little startup time; kernel-level tools cost setup effort.

Setting up Docker Sandboxes

Docker Sandboxes (CLI name: sbx) launches each coding agent inside a disposable microVM with its own kernel, filesystem and Docker daemon, so builds, installs and even containers the agent creates stay off your host machine. On macOS, install it with `brew install docker/tap/sbx` and run `sbx login`; on first login you choose a default network policy for every sandbox you create afterward.

To launch an agent, run `sbx run claude` (or `codex`, `copilot`, `cursor`, or any of the other agents sbx supports) from your project directory. By default this gives the agent read-write access to your working tree; pass `--clone` instead to have it work on a private git clone while your real repo stays mounted read-only.

Network policy is where most of the real protection lives. `sbx policy set-default deny-all` blocks every outbound request by default, and `sbx policy allow network "api.anthropic.com,*.npmjs.org"` opens exactly the hosts you name. Watch the wildcard syntax: `example.com` does not match its subdomains and `*.example.com` does not match the bare domain, so list both if you need both. `sbx policy reset` clears your rules back to the default if you get stuck, and `sbx policy ls` shows what is actually in force.

  • Install: `brew install docker/tap/sbx` then `sbx login`.
  • Launch: `sbx run claude` from the project directory, or `--clone` for a read-only host repo.
  • Lock down the network: `sbx policy set-default deny-all`, then allow only named hosts.
  • Each sandbox gets its own kernel, filesystem and Docker daemon.

macOS native isolation with sandbox-exec

If you want zero virtualization overhead and are comfortable writing your own rules, macOS has shipped a built-in tool called sandbox-exec since OS X 10.5, built on a kernel framework developers call Seatbelt. Apple marked the public command deprecated back in Sierra, but it is still fully functional on current macOS releases and several production coding tools, including Anthropic's own Claude Code sandbox, use the same Seatbelt mechanism underneath a friendlier interface.

To use it directly, you write a Scheme-syntax profile that starts by denying everything, then adds back exactly what the agent needs: read-write on the project folder, read-only on a few system paths, and nothing on your home directory or SSH keys. Running `sandbox-exec -f profile.sb your-agent-command` applies that profile to the process at the kernel level, before the process gets to do anything else.

The failure mode is getting the profile wrong in either direction. Too strict, and the agent cannot find its compiler or write its own temp files. Too loose, and you have written yourself a sandbox that does not actually sandbox anything. Plan to iterate on the profile against your real build, not a hello-world script.

  • sandbox-exec has shipped in macOS since 10.5, built on the Seatbelt framework.
  • Apple deprecated the public command years ago; it still works on current macOS.
  • A profile starts with deny-everything, then allows specific paths.
  • Test the profile against your actual build, since an overly strict one breaks it silently.

Managing secrets inside the sandbox

A sandbox protects your host files. It does nothing for a secret that is inside the sandbox with the agent. Mounting your real .env file into a Docker Sandbox or a sandbox-exec profile just moves the leak surface, it does not close it, since the agent can still read that file and anything it reads can end up in a model's context or a transcript.

Inject credentials at the moment a command needs them instead. Docker Sandboxes has a command for this: `sbx secret set SERVICE --sandbox SANDBOX_NAME` scopes a credential to one sandbox, and the sandbox's network proxy resolves it into the matching outbound request rather than writing it to a file the agent can open. On a plain sandbox-exec setup, the equivalent is pulling the value from the macOS Keychain inside a wrapper script right before the real command runs, so it exists in memory for one command and nowhere else.

  • Never mount a plain .env file into a sandbox; it is still readable there.
  • `sbx secret set SERVICE --sandbox SANDBOX_NAME` scopes a credential to one sandbox.
  • On sandbox-exec, pull secrets from the Keychain in a wrapper script at run time.
  • A secret should exist in memory for one command, not as a standing file.

How Forkbench handles local sandboxing

Forkbench is a desktop app that runs coding agents in a real terminal on your Mac. Rather than wrapping each agent in a separate microVM, it integrates directly with your local system and leans on its own Vault for secrets: a credential stored there sits in the macOS Keychain and is handed to a command by name, so the raw value never has to sit in a project file.

The limits matter as much as the feature. A Vault key that is not pinned to a specific command can still be read by whatever program you let that key run. Forkbench's folder lock stops an agent from touching files outside the project you locked it to, but it is opt-in and it does not restrict the network at all, so an agent can still make outbound requests unless you add your own firewall rule or a tool like sbx underneath it.

That makes Forkbench a good fit for supervised, everyday development where you want native speed and you are willing to pair it with your own network controls. For code you genuinely do not trust, a microVM boundary like Docker Sandboxes is the stronger guarantee.

  • Forkbench runs agents natively, without a separate microVM per agent.
  • The Vault stores secrets in the Keychain and injects them by name.
  • A Vault key not pinned to a command can be read by the program that runs.
  • Folder lock is opt-in and covers files, not network traffic.

Adding a human approval gate

Isolation protects your host machine, not your judgment. An agent inside a perfect sandbox can still write broken code, delete the wrong file within its own workspace, or push a bad commit to a remote repo if it holds a credential that can do that.

Set a rule for yourself: anything that reaches outside the sandbox, a `git push`, a deploy command, a `terraform apply`, needs a human to read it and say yes before it runs. That single habit catches more real incidents than an extra layer of container isolation does.

  • A sandbox stops damage to your host, not bad code inside the sandbox.
  • Require a human read-and-approve step before any command that leaves the sandbox.
  • Push, deploy and infrastructure commands are the ones to gate first.

Matching the sandbox to the workload

A microVM boundary like Docker Sandboxes is the right default for untrusted or exploratory work, new agents you have not used before, dependencies you have not vetted, tasks where you expect the agent to install things. The startup cost per sandbox is small enough not to matter for normal development.

sandbox-exec is the better choice when you are iterating fast on a trusted toolchain and the microVM's overhead, small as it is, actually shows up in your workflow, for example a tight compile-test-fix loop on a large codebase. Most developers end up using both: a locked-down profile for day-to-day work, and a full microVM for anything new or unverified.

Related: Forkbench vs Docker Sandboxes, Sandboxing coding agents with macOS Seatbelt, An agent read my API keys. What now?, How Forkbench handles your data

Frequently asked

  • What is the best sandbox setup for a beginner?

    Docker Sandboxes. Install the sbx CLI with brew install docker/tap/sbx, run sbx login, and you get a working microVM boundary with a sane default network policy in two commands, without writing a kernel-level profile by hand.

  • Can a sandboxed agent reach the internet freely?

    Only if you let it. Docker Sandboxes defaults to a policy you choose at login; run sbx policy set-default deny-all and then allow specific hosts with sbx policy allow network to keep it locked down.

  • Does sandbox-exec work on Windows or Linux?

    No, it is a macOS-only tool built on the Seatbelt framework. On Linux the rough equivalent is Bubblewrap or a locked-down Docker container; on Windows it is Windows Sandbox or WSL2 with Docker.

  • Is Forkbench's folder lock enough on its own?

    No. It is opt-in and it stops file access outside the project you locked, but it does not restrict the network. Pair it with your own firewall rule or a tool like Docker Sandboxes if you need network isolation too.

Keep reading