Skip to main content
Glama

docker-agent-sandbox

Let your AI agent run code. Just not on your machine.

Coding agents are at their most useful when they can execute what they write: test a function, crunch a CSV, check a regex. They are at their most dangerous for exactly the same reason. One hallucinated rm -rf, one prompt-injected curl | sh, and the agent is acting with your permissions on your laptop.

docker-agent-sandbox (das) gives agents a safe place to run code. Every execution gets a fresh, throwaway Docker container with:

Control

Setting

What it stops

Network

--network none

Data exfiltration, downloading payloads, calling home

Filesystem

--read-only root, in-memory /tmp (noexec)

Tampering with the image, dropping binaries

Host access

Code streamed on stdin, no volume mounts

Reading your SSH keys, .env files, source tree

Privileges

--cap-drop ALL, no-new-privileges, user 65534 (nobody)

Privilege escalation, setuid, raw sockets

CPU / memory

--cpus 0.5, --memory 256m (no swap)

Crypto-mining, memory exhaustion

Processes

--pids-limit 64

Fork bombs

Time

Hard timeout, then docker kill

Infinite loops, hung jobs

Output

Capped (64 KB by default)

Flooding the agent's context window

Lifetime

--rm

Leftover state between runs

It ships as a CLI for humans and CI, and an MCP server so any MCP-capable agent (Claude Desktop, goose, VS Code, Cursor, or anything behind the Docker MCP Gateway) gets a run_code tool that can only ever execute inside that box.

No runtime dependencies beyond Python 3.10+ and the Docker CLI.

Quick start

pip install git+https://github.com/shriramkv/docker-agent-sandbox
docker pull python:3.12-slim

echo 'print(sum(range(10)))' | das run -
# 45
# [sandbox] success in 0.41s

Now try something an agent should never be allowed to do:

das run examples/escape_attempts.py
running as uid=65534 gid=65534
[BLOCKED ] outbound network connection: OSError
[BLOCKED ] write to /etc/passwd: PermissionError
[BLOCKED ] drop a file in /usr/local/bin: OSError
[BLOCKED ] setuid(0): PermissionError
[BLOCKED ] effective capabilities = 0000000000000000
[OK      ] /tmp is writable scratch space (in-memory, discarded after the run)
[sandbox] success in 0.27s

Related MCP server: MCP Powered AI Assistance

See exactly what runs

No magic. das explain prints the precise docker run command, which makes this a handy teaching tool for container hardening in its own right:

das explain
docker run \
  --rm \
  -i \
  --name das-<random> \
  --network none \
  --read-only \
  --tmpfs /tmp:rw,noexec,nosuid,nodev,mode=1777,size=32m \
  --memory 256m \
  --memory-swap 256m \
  --cpus 0.5 \
  --pids-limit 64 \
  --cap-drop ALL \
  --security-opt no-new-privileges \
  --user 65534:65534 \
  --workdir /tmp \
  --env HOME=/tmp \
  --env PYTHONDONTWRITEBYTECODE=1 \
  --label docker-agent-sandbox=1 \
  python:3.12-slim python -I -

Use it from an agent (MCP)

das mcp --policy examples/strict-policy.json --audit-log ~/das-audit.jsonl

Claude Desktop (claude_desktop_config.json):

{
  "mcpServers": {
    "docker-sandbox": {
      "command": "das",
      "args": ["mcp", "--policy", "/absolute/path/to/strict-policy.json"]
    }
  }
}

The server exposes one tool:

  • run_code: code (required), language (python, node or shell), timeout_seconds (optional).

An agent may shorten the timeout but can never lengthen it beyond the server policy, and it cannot switch the network on. Those decisions belong to the human who started the server, not to the model. Results come back as readable text plus structuredContent (exit code, verdict, duration, truncation flag), and failures set isError so the agent can see and react to them.

Policies

Defaults are strict. Loosen them deliberately, in a file you can review:

{
  "timeout_seconds": 5,
  "memory_mb": 128,
  "cpus": 0.25,
  "pids_limit": 32,
  "network": false,
  "images": { "python": "python:3.12-slim" }
}
das policy --policy my-policy.json      # print the effective policy
das run job.py --memory 512 --timeout 30 # per-run overrides
das run job.py --allow-network           # explicit, and warned about

Policies are validated: running as root is refused, unknown keys are rejected, and every limit has a sane range.

Audit trail

--audit-log appends one JSON line per execution: timestamp, language, image, verdict, exit code, duration and the policy limits in force. The code itself is stored only as a SHA-256 hash, so the log shows what ran and when without becoming a second copy of whatever the agent wrote.

{"timestamp": "2026-11-03T13:05:12+00:00", "language": "python", "image": "python:3.12-slim", "code_sha256": "9f2c...", "exit_code": 0, "verdict": "success", "duration_seconds": 0.38, "timed_out": false, "truncated": false, "network": false, "memory_mb": 256, "cpus": 0.5}

Use it as a library

from docker_agent_sandbox import SandboxPolicy, run_code

result = run_code("print(2 ** 64)", policy=SandboxPolicy(timeout_seconds=3))
print(result.verdict, result.stdout)

What this is not

A container is a strong boundary, not a perfect one; it shares the host kernel. For genuinely hostile, multi-tenant workloads, pair this with a stronger runtime such as gVisor (--runtime runsc) or a microVM, and keep the Docker daemon itself patched. Also note that das drives your local Docker CLI, so whoever can start the MCP server already has Docker access; the sandbox protects you from the agent, not from yourself.

Development

pip install -e ".[dev]"
pytest -q                      # unit tests, no Docker needed (a fake docker CLI is used)
DAS_INTEGRATION_IMAGE=python:3.12-slim pytest -q -m integration   # real containers
ruff check . && ruff format --check .

The integration suite proves each control against a real daemon: non-root user, network blocked, read-only root with writable /tmp, zero capabilities, fork bomb contained, memory hog killed (exit 137) and infinite loop timed out.

Licence

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to execute arbitrary Python code securely in a sandboxed environment with resource limits and security constraints via MCP protocol.
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to safely execute Python, JavaScript, and Bash code in an isolated Docker sandbox with strict security constraints.
    1
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables secure execution of Python scripts in isolated Docker containers via MCP, with resource limits, package allowlisting, read-only filesystem, and artifact return.
    MIT