Run AI coding agents in a locked-down local sandbox with:
- Minimal filesystem access (only your repo + project-scoped agent state)
- Restricted outbound network (iptables-based allowlist)
- Reproducible environments (Debian container with pinned dependencies)
Target platform: Colima + Docker Engine on Apple Silicon. Should work on any Docker-compatible runtime.
Creates a sandboxed environment for Claude Code that:
- Blocks all outbound network traffic by default
- Allows only specific domains (GitHub, npm, Anthropic APIs, etc.)
- Runs as non-root user with limited sudo for firewall setup
- Persists Claude credentials in a Docker volume across container rebuilds
Two modes are supported, using the same images:
| Mode | Best for | How to use |
|---|---|---|
| Devcontainer | VS Code users | Open project in Dev Container |
| Compose | CLI users, non-VS Code editors | docker compose up -d && docker compose exec agent zsh |
Both modes provide identical sandboxing. The difference is how the firewall gets initialized:
- Devcontainer: VS Code bypasses Docker entrypoints, so firewall runs via
postStartCommand - Compose: Firewall runs via the container's entrypoint script
Choose based on your editor preference. The quick start below covers both.
brew install colima docker docker-compose
colima start --cpu 4 --memory 8 --disk 60If you previously used Docker Desktop, set your Docker credential helper to osxkeychain (not desktop) in ~/.docker/config.json.
git clone https://github.com/mattolson/agent-sandbox.git
cd agent-sandbox
./images/build.shThis builds agent-sandbox-base:local and agent-sandbox-claude:local.
Copy the .devcontainer directory to your project:
cp -R agent-sandbox/.devcontainer /path/to/your/project/Then open your project in VS Code:
- Install the Dev Containers extension
- Command Palette -> Dev Containers: Reopen in Container
Copy docker-compose.yml to your project:
cp agent-sandbox/docker-compose.yml /path/to/your/project/Then start the container:
cd /path/to/your/project
docker compose up -d
docker compose exec agent zshFrom your host terminal (not the VS Code integrated terminal):
# Find your container name
docker ps
# Exec into it
docker exec -it <container-name> zsh -i -c 'claude'This triggers the OAuth flow:
- Copy the URL and open it in your browser
- Authorize the application
- Paste the authorization code back into the terminal
- Type
/exitto close Claude
Credentials persist in a Docker volume. You only need to do this once per project.
From inside the container:
claude
# or for auto-approve mode:
yolo-claudeFor compose mode, stop the container when done:
docker compose downThe firewall (images/base/init-firewall.sh) blocks all outbound by default. Currently allowed:
- GitHub (api, web, git) - IPs fetched dynamically from api.github.com/meta
- registry.npmjs.org
- api.anthropic.com - for Claude Code operations
- sentry.io, statsig.anthropic.com, statsig.com - for Claude Code telemetry
- VS Code marketplace and update servers
To add a domain: edit images/base/init-firewall.sh, add to the domain loop, rebuild the images with ./images/build.sh.
The firewall is initialized by init-firewall.sh, which:
- Creates an ipset for allowed IPs
- Resolves each allowed domain and adds IPs to the set
- Fetches GitHub's IP ranges from their meta API
- Sets iptables rules to DROP all outbound except to the ipset
- Verifies the firewall by testing that example.com is blocked and api.github.com works
Initialization differs by mode:
- Compose mode: The entrypoint script runs
init-firewall.shautomatically - Devcontainer mode: VS Code bypasses entrypoints, so
postStartCommandtriggers initialization
The script is idempotent (checks for existing rules before running), so both paths work correctly.
The container runs as a non-root dev user with passwordless sudo only for the firewall setup commands.
This project reduces risk but does not eliminate it. Local dev is inherently best-effort sandboxing. For example, operating as a VS Code devcontainer opens up a channel to the IDE and installing extensions can introduce risk.
Key principles:
- Minimal mounts: only the repo workspace + project-scoped agent state
- Prefer short-lived credentials (SSO/STS) and read-only IAM roles
- Firewall verification runs at every container start
- Run long-lived agent sessions in tmux so VS Code reconnects don't kill the process
Project plan can be seen in docs/plan/project.md and related files, but here is the overview:
Extract .devcontainer/ into a reusable template with:
- Split Dockerfile into base + agent-specific images
- Policy YAML file for configurable domain allowlists
- Documentation for adding to other projects
- Build and publish images to GitHub Container Registry
- Pin images by digest for reproducibility
agentbox init- scaffold devcontainer from templateagentbox bump- update image digestsagentbox policy- manage allowlist domains
- Support for Codex, OpenCode, and other agents
- Agent-specific images and configuration
- Proxy-based network enforcement for request-level logging
- Docker Compose stack with structured audit logs
PRs welcome for:
- New agent support
- Improved network policies
- Documentation and examples
Please keep changes agent-agnostic where possible and compatible with Colima on macOS.
If you find a sandbox escape or bypass:
- Open a GitHub Security Advisory (preferred), or
- Open an issue with minimal reproduction details