Skip to content

gbrindisi/agentbox

Repository files navigation

Agentbox

A sandbox for running autonomous coding agents with network and filesystem isolation.

Coding agents are most useful when they can run autonomously, but this introduces risks: rogue activities, data exfiltration, or unintended external communications. Agentbox provides a containerized sandbox around any agent, with sensible defaults for quick setup and enough flexibility to customize for your needs.

The Security Model

Running agents autonomously means giving them significant control over your system. An agent with unrestricted network access could exfiltrate code to external servers. An agent with full filesystem access could read sensitive credentials or modify critical files.

Agentbox implements defense in depth to mitigate these risks:

Layer Protection What It Prevents
Network firewall iptables default-deny policy Data exfiltration, unauthorized API calls, C2 communication
Privilege separation Root configures firewall, then drops to unprivileged user Agent cannot modify firewall rules or access privileged operations
Capability dropping All Linux capabilities removed via setpriv Prevents kernel-level exploits and privilege escalation
No new privileges Blocks setuid/setgid binaries Prevents exploitation of SUID binaries for privilege escalation
Seccomp filtering Restricts available syscalls Limits attack surface for container escapes
No sudo sudo not installed in container Eliminates common privilege escalation vector

This is a best-effort, defense-in-depth approach. Container escape vulnerabilities could bypass all protections. The goal is to significantly raise the bar for malicious behavior while maintaining agent usability.

Quick Start

Requirements:

  • Docker (Docker Desktop on macOS, native Docker on Linux)
  • Go 1.21+ (for building from source)

Install:

git clone https://github.com/gbrindisi/agentbox.git
cd agentbox
make build
sudo make install

Run:

agentbox init --profile claude-code
export ANTHROPIC_API_KEY=sk-...
agentbox run -- "2+2=?"

Note: On macOS, use this to inherit an existing Claude Code session:

ANTHROPIC_API_KEY=$(security find-generic-password -w -s "Claude Code") agentbox run -- "2+2=?"

Configuration

The sandbox is defined in an Agentfile, a YAML configuration file auto-discovered in the current directory.

# agentbox configuration
# See: https://github.com/gbrindisi/agentbox

# Agent configuration
agent:
  # Build script runs as root during image build to install tools
  build_script: |
    curl -fsSL https://claude.ai/install.sh | bash
    # Copy claude to system-wide location (install script puts it in ~/.local/bin)
    cp /root/.local/bin/claude /usr/local/bin/claude

  # Command and arguments to run
  command: ["claude"]
  args: ["--dangerously-skip-permissions", "--print"]

  # Environment variables to pass from host to container
  # Supports glob patterns like CLAUDE_CODE_*
  env_passthrough:
   - ANTHROPIC_API_KEY
  #  - CLAUDE_CODE_*

# Workspace configuration
workspace:
  # Directory to mount as /workspace in the container
  # Default: current directory
  path: /path/to/code

# Additional mounts (optional)
mounts:
  - source: $HOME/.claude
    target: /home/agent/.claude
    readonly: false

# Network configuration
network:
  # Composable presets for services your agent needs
  presets:
    - anthropic
    - github
    - npm
    - pypi

  # Additional custom domains or ips (optional):
  # allow:
  #   - custom-api.example.com

# Container security settings (optional)
# container:
#   no_new_privileges: true    # Prevent privilege escalation (default: true)
#   readonly_root: false       # Make root filesystem read-only
#   seccomp_profile: default   # Seccomp profile: default, unconfined, or path

Build Script

Install tools and dependencies at image build time. Runs as root during docker build, result is cached based on script content hash.

agent:
  build_script: |
    apt-get update && apt-get install -y nodejs npm
    npm install -g my-tool

Use --rebuild to force a rebuild (Docker layer cache still applies). Runtime execution always runs as unprivileged agent user.

Environment Variables

Pass environment variables from host to container using glob patterns:

agent:
  env_passthrough:
    - ANTHROPIC_API_KEY    # Exact match
    - CLAUDE_CODE_*        # Glob pattern
    - AWS_*                # All AWS variables

Mounts

Mount host directories into the container:

mounts:
  - source: ~/.ssh
    target: /home/agent/.ssh
    readonly: true
  - source: ~/.gitconfig
    target: /home/agent/.gitconfig
    readonly: true

Firewalling

The firewall uses iptables with a default-deny OUTPUT policy. At container startup, allowed domains are resolved to IP addresses using dig and stored in an ipset for efficient matching. DNS queries are restricted to the container's DNS server only. IPv6 is blocked by default to prevent bypass.

A companion libsandbox.so library is injected via LD_PRELOAD to intercept connect() calls. When a connection to a blocked IP is attempted, instead of a silent timeout, the agent receives an informative error message:

agentbox: Connection to 203.0.113.50 blocked by sandbox firewall. This is not bypassable.

This helps agents understand why a connection failed and adjust their behavior accordingly, rather than retrying indefinitely or misdiagnosing the issue.

Control network access with composable presets or custom domain lists:

# Combine presets for the services your agent needs
network:
  presets:
    - anthropic
    - github
    - npm

# Add custom domains alongside presets
network:
  presets:
    - anthropic
  allow:
    - custom-api.example.com

Available presets:

Category Preset Domains
AI Providers anthropic api.anthropic.com, anthropic.com, claude.ai
openai api.openai.com, openai.com, platform.openai.com, cdn.openai.com
google-ai generativelanguage.googleapis.com, ai.google.dev, aistudio.google.com
mistral api.mistral.ai, mistral.ai
Source Control github github.com, api.github.com, raw.githubusercontent.com, objects.githubusercontent.com, codeload.github.com
gitlab gitlab.com, registry.gitlab.com
bitbucket bitbucket.org, api.bitbucket.org
Package Registries npm registry.npmjs.org, npmjs.org, npmjs.com
pypi pypi.org, files.pythonhosted.org
cargo crates.io, static.crates.io, index.crates.io
rubygems rubygems.org
ML/AI Models huggingface huggingface.co, cdn-lfs.huggingface.co

Container Settings

Fine-tune container security:

container:
  no_new_privileges: true    # Prevent privilege escalation (default: true)
  readonly_root: false       # Make root filesystem read-only
  seccomp_profile: default   # default, unconfined, or path to custom profile

CLI Commands

agentbox init

Create a new Agentfile from a profile template.

agentbox init                         # Uses claude-code profile
agentbox init --profile claude-code   # Explicit profile

agentbox run

Run an agent in the sandbox.

agentbox run                          # Run with auto-discovered Agentfile
agentbox run -c /path/to/Agentfile    # Specific config file
agentbox run -w /path/to/project      # Override workspace directory
agentbox run --rebuild                # Force image rebuild
agentbox run --tty                    # Force TTY allocation
agentbox run --no-tty                 # Disable TTY allocation
agentbox run --debug                  # Enable debug output
agentbox run -- "your prompt here"    # Pass arguments to agent

agentbox validate

Validate an Agentfile without running.

agentbox validate
agentbox validate -c /path/to/Agentfile

agentbox shell

Open a debug shell in the container. Uses the same configuration as run but starts bash instead of the agent. Useful for testing firewall rules and inspecting the environment.

agentbox shell                        # Open shell with auto-discovered Agentfile
agentbox shell --rebuild              # Force image rebuild before opening shell
agentbox shell --debug                # Enable debug output

Good to Know

Limitations

  • DNS at startup: Domain names are resolved to IPs when the container starts. Long-running containers won't pick up DNS changes.
  • Container escapes: A container escape vulnerability would bypass all protections. This is defense in depth, not a security guarantee.
  • Mount access: The agent has full access to all mounted directories within the container.

File Ownership Issues

Files created by the agent are owned by UID 1000 (the agent user). On Linux, this may differ from your host UID.

Solutions:

  1. Run chown after the container exits
  2. Match UIDs in your build script:
agent:
  build_script: |
    usermod -u 501 agent      # Replace 501 with your UID
    groupmod -g 501 agent
    chown -R agent:agent /home/agent

Note: The container must start as root to configure the firewall before dropping privileges, so runtime UID cannot be overridden.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors