Agent sandbox sized to blast radius

Agentic AI Platform Engineering Reference build

A reference build for capability-based agent isolation: sandboxes scoped to minimum required permissions, with resource limits, egress controls, and blast radius containment for untrusted agent code.

Architecture diagram: agent code runs in isolated sandbox with capability tokens; resource limits (CPU, memory, time); egress proxy filters network calls; audit trail logs all actions.
Representative architecture: sandboxes are scoped to minimum capabilities; resource limits prevent abuse; egress proxy enforces allowlists; all actions are audited.

The problem

Most agent frameworks run code with the same privileges as the host process: full filesystem access, unrestricted network egress, and the ability to consume unbounded compute. This works for trusted agents in controlled environments. It fails catastrophically when agents execute untrusted code, integrate third-party plugins, or operate in multi-tenant contexts. A single compromised or misbehaving agent can exfiltrate data, consume all resources, or pivot to attack other systems.

The category error is treating isolation as an afterthought — a firewall rule or container boundary applied post-hoc. The real requirement is capability-based security from the ground up: agents receive only the permissions they need, for the resources they access, for the duration of their execution. The blast radius of any single agent is bounded by design, not by hope.

The constraints

This is a reference build, so the constraints mirror production multi-tenant scenarios: the sandbox must isolate filesystem access (read/write scopes), network egress (allowlisted domains, request inspection), compute resources (CPU, memory, time limits), and identity (scoped credentials, no privilege escalation). All agent actions must be auditable. The sandbox must be fast enough for interactive use while preventing abuse. And the isolation must be enforceable — not just advisory — so a compromised agent cannot escape its bounds.

The decisions

Five of them, each a rejection of a permissive default.

Capabilities are explicit tokens, not ambient authority. The build rejects the pattern of "agent runs as the user." Instead, agents receive capability tokens at startup: read access to `/data/public`, write access to `/tmp/agent-work`, network access to `api.example.com`. This is permission architecture for agents made load-bearing: no ambient authority, only explicitly granted capabilities.

Resource limits are enforced by Docker, not advisory. CPU time, memory, wall-clock time, and network bandwidth are all limited per agent. Limits are enforced by the Docker daemon at the kernel level via cgroups — not by polite requests to the agent. An agent that exceeds its memory limit is OOM-killed; one that exceeds CPU quota is throttled; one that runs too long is terminated. This is the same pattern Kubernetes uses: resource quotas are hard constraints, not suggestions.

Egress is proxied and inspected. Network calls don't go directly from agent to internet. They flow through an egress proxy that enforces allowlists, inspects request/response sizes, and logs all traffic. The proxy can block exfiltration attempts, rate-limit calls, and inject authentication headers. This applies privacy as a data-flow architecture to agent egress.

Filesystem access is scoped and virtualized. Agents don't see the host filesystem. They see a virtualized view: mounted directories with read/write/read-write permissions, temporary storage that's cleaned up on exit, and no ability to traverse outside their sandbox. This is container-style filesystem isolation applied to agent execution.

Audit trail is reconstructable. Every agent action is logged: capabilities used, resources accessed, network calls made, limits hit. An auditor can reconstruct what an agent did, what it tried to do, and where it was stopped. This is the same evidentiary standard as audit trails that answer who acted with what authority.

The outcome

The build answers the three questions a production agent sandbox must answer and a naive executor cannot: what can this agent access, what resources can it consume, and what did it actually do. Capabilities bound the blast radius. Resource limits prevent abuse. Egress controls block exfiltration. And the audit trail reconstructs every action.

The honest caveat: this is a reference build demonstrating Docker-based isolation, not a security-certified sandbox with kernel hardening or seccomp profiles. The isolation is real — container escape requires a kernel exploit, not ignoring a Python check — but production hardening would add read-only root filesystems, dropped capabilities, and AppArmor/SELinux profiles. The point of the build is the architecture: agent isolation is container-based with capability-granted mounts and network access, not cooperative Python checks.

Reference implementation

The pattern is instantiated as a runnable Python reference implementation — a Docker-based agent sandbox with capability-granted volume mounts, kernel-enforced resource limits (cgroups), egress proxy, and audit logging. The sandbox executes agent code in isolated containers with explicitly granted capabilities: filesystem access via mounted volumes (read-only or read-write), network access via allowlist-filtered egress proxy, and resource limits enforced by Docker (CPU quota, memory limit, wall-clock timeout).

The implementation includes five self-checking scenarios: normal execution in isolated container, resource limit enforcement (Docker OOM kill, CPU throttling), egress control (allowlist/denylist), filesystem isolation (mounted paths only), and audit trail reconstruction. A demo script drives an agent through each scenario and prints the capabilities granted, limits enforced, and audit log.

The full source — Docker runtime, capability manager, egress proxy, audit logger — is public at github.com/Dhristhi/agent-sandbox-blast-radius, under the Apache-2.0 license.

What you can run

git clone https://github.com/Dhristhi/agent-sandbox-blast-radius
cd agent-sandbox-blast-radius
uv sync --extra dev

# Pull base image (requires Docker)
docker pull python:3.12-slim

# Run scenarios (Docker isolation)
uv run python scripts/scenario_1_normal.py
uv run python scripts/scenario_2_resource_limits.py
uv run python scripts/scenario_3_egress_control.py
uv run python scripts/scenario_4_filesystem_isolation.py
uv run python scripts/scenario_5_audit_trail.py

# Run all tests (mocked Docker)
uv run pytest -q