Your AI agent can read your repo, run your tests, and open a pull request. It can also talk itself into doing things you never asked for.
That's not fear-mongering — it's observed behavior. Given a goal and a set of tools, agents rationalize extra steps, escalate privileges when a task gets hard, and repeat secrets to whatever endpoint will listen. And every constraint you wrote into the system prompt? That's advice, not enforcement. A probabilistic text generator can — and sometimes will — reason its way right past it.
The fix isn't a better-behaved model. It's a wall the model can't argue with: a sandbox at the execution layer that enforces what the network, the credentials, and the filesystem actually expose, no matter what the agent decides it needs.
Sandboxing an AI agent means running each session inside an enforced isolation boundary — typically a microVM or hardened container — so the agent's actions physically cannot reach your host, credentials, or network beyond an explicit allowlist. Prompt-level rules are advisory and can be reasoned past; OS- and hypervisor-level boundaries cannot. The practical setup combines strong isolation primitives, default-deny networking, ephemeral scoped tokens, read-only mounts, RPC facades for dangerous tools, and immutable audit logs covering every session.
Advisory rules vs enforced boundaries
Understand this distinction and everything else in the guide follows:
| Advisory (in the model) | Enforced (at the execution layer) | |
|---|---|---|
| Where it lives | System prompt, policy text, "constitution" | Hypervisor, kernel, network policy, vault |
| What happens on violation | The agent may rationalize and proceed | The action physically fails |
| Defends against | Well-behaved tasks going slightly off-script | Malicious prompts, confused agents, buggy policies |
| Auditable? | Only if the model chooses to explain | Yes — the OS logs what actually happened |
Three realities drive the design:
- Advisory controls are fragile. Prompts can be manipulated; a chain of thought can justify rule-breaking one plausible step at a time.
- Agents are good at affordance discovery. If a tool can be used, a determined agent will find a way to use it.
- The host is the ultimate single point of failure. Whatever the sandbox can reach, a compromised session can reach.
What "zero blast radius" actually means
The phrase gets used loosely. Operationally, it means four concrete properties:
- The agent cannot access host resources beyond the sandbox boundary.
- Network access is scoped to explicitly allowed hosts; everything else is blocked.
- Credentials are never directly visible inside the sandbox unless injected deliberately, with an audit trail.
- Side effects are ephemeral — filesystem writes and outbound requests live in artifacts you can audit, then destroy.
Zero blast radius doesn't prevent bad outputs inside the sandbox. It prevents those outputs from touching anything you care about.
Choosing an isolation primitive
| Primitive | Strengths | Weaknesses | Best for |
|---|---|---|---|
| MicroVM | Hardware virtualization boundary; predictable properties; small attack surface when minimized | Slower cold start; slightly higher resource overhead | High-assurance work where credential safety and network isolation matter most |
| Container + kernel hardening | Fast startup; mature tooling; resource-efficient | Weaker if kernel compromise is in your threat model; needs seccomp, user namespaces, strict cgroups | Developer workflows needing speed with reasonable isolation |
| Userspace sandbox | Fine-grained control per runtime (JVM, Python) | Hard to secure comprehensively; native extensions escape | Mitigating untrusted code when OS-level sandboxing isn't possible |
| Hybrid | MicroVM outside, containers inside for portability; RPC bridge for privileged services | More moving parts | Production agent platforms |
For agent workloads that touch credentials or private code, microVMs are the default recommendation: the isolation boundary doesn't depend on the host kernel staying clean.
Network controls: default deny, explicitly allow
Network egress is the main exfiltration path. The policy is boring and non-negotiable: block everything, allow exactly what the session needs.
- Default-deny inbound and outbound; allow only explicit endpoints.
- Use short-lived, scoped proxies for allowed services — say, one internal git host and one test runner.
- Log every outbound request to a central auditor.
- Filter DNS and strip sensitive headers at the egress proxy.
The allowlist is policy, so keep it as code:
# sandbox-net-policy.yaml — the only egress this session gets
default: deny
allow:
- host: git.internal.example
port: 443
proto: https
reason: "clone + push PR branch"
- host: test-runner.internal.example
port: 443
proto: https
reason: "submit test runs"
deny_and_log:
- "169.254.169.254" # cloud metadata — never
- pattern: "*.amazonaws.com"
- pattern: "*"
If the agent tries anything not on the list, the connection dies at the wall — and the attempt lands in the audit log.
Credentials: ephemeral, scoped, revocable
Never bake long-lived keys into a sandbox image, and never export them as environment variables that persist across sessions. The pattern that works:
- Fetch at startup, not at build — ephemeral credentials minted per session.
- Minimal scope — one repo, read-only, or a single pre-approved fork.
- Short TTL — minutes, not days.
- Logged and revoked at teardown, no exceptions.
A token spec the orchestrator can mint and audit:
{
"session": "agent-7f3a",
"credential": "one-time-git-token",
"scope": ["repo:acme/api:read", "fork:acme/api-prs:push-branch"],
"ttl_minutes": 10,
"delivered_via": "authenticated_local_channel",
"revoked_on": "sandbox_teardown",
"audit": "credential-issue + credential-revoke logged to immutable store"
}
When the session ends — or behaves oddly — the token is dead before the agent could reuse it.
Filesystem and tools: least privilege by design
- Mount only the repo directories or snapshots the session needs; read-only when the agent shouldn't change source, with one controlled writable area for branches and artifacts.
- Snapshot the repo state at sandbox creation — reproducible sessions are auditable sessions.
- Whitelist binaries and versions explicitly; no shell path surprises.
- Replace dangerous capabilities with façades: instead of a deploy command, expose a
request-deployRPC that runs authorization checks, logs the request, and can route to human review.
{
"tool": "deploy",
"exposed_as": "rpc:request-deploy",
"direct_access": false,
"policy": {
"requires": ["green-tests", "signed-commits"],
"on_request": "log + policy-engine-review",
"fallback": "human-approval-queue"
}
}
The agent never holds the keys to production; it holds a doorbell.
Observability: if you can't see it, you can't secure it
Instrument the whole lifecycle: session creation and teardown, full network egress metadata, command history inside the sandbox, filesystem changes, artifact uploads, and every credential issued or revoked. Ship it all to an immutable audit store with retention and search — and capture session replays (terminal output, API traces) when you can. When something goes sideways, the audit trail is how you prove what happened and close the gap.
What isolation costs
| Factor | MicroVM | Hardened container |
|---|---|---|
| Cold start | ~100 ms to a few seconds | Often <100 ms warm |
| Memory | Owns a small kernel + fixed allocation | Shares host kernel; lighter |
| Security boundary | Hardware virtualization | Kernel features (seccomp/namespaces) |
Mitigations that make microVMs practical: keep images minimal, pre-warm pools of VMs with strict ephemeral-state reset between sessions, and use copy-on-write filesystems so workspace instantiation is instant.
The safe session lifecycle

- Request — developer submits a session with explicit scope (repo, tests, tools).
- Provision — orchestration creates the sandbox with policy attached: network allowlist, ephemeral tokens, mounts.
- Run — the agent works strictly inside those bounds.
- Audit — every action lands in the immutable store under the session ID.
- Teardown — sandbox destroyed, tokens revoked, artifacts exported to a controlled store.
Automate all five steps and wire them into the tools developers already use — friction is what makes people bypass safety.
When the agent misbehaves
Design the failure modes before you need them:
- Disallowed network access → blocked at the wall, logged, optionally paged to a human.
- Requests for elevated credentials → routed to approval, never auto-granted.
- Suspicious mid-session behavior (a burst of unusual egress) → snapshot the sandbox, freeze the session, preserve logs.
Write the incident playbook now: snapshot collection, token revocation, remediation steps.
Worked example: the code-gen agent
The setup that lets an agent clone, test, and open PRs safely:
- Read-only repo snapshot + writable
/workfor the PR branch. - Network: git host + internal test runner only.
- Ephemeral token scoped to branch creation on a pre-approved fork.
- No production endpoints, no metadata services, no exceptions.
- A pull-request façade that verifies tests and enforces commit signing before the PR exists.
The agent does useful work. The blast radius stays inside the box.
Mistakes to avoid
- Trusting model-level constraints as your only control.
- Long-lived credentials baked into images or env vars.
- Broad network access "just during development."
- Skipping audit logs for speed.
- Running sandbox orchestration on the same sensitive host it's supposed to protect.
The checklist
- Define the threat model before the sandbox config.
- Strong isolation primitives (microVM for high assurance).
- Default-deny networking with explicit allowlists.
- Ephemeral, scoped credentials — revoked at teardown.
- Read-only mounts; one controlled write area.
- RPC façades for dangerous tools.
- Immutable, centralized audit logging.
- Automated lifecycle with an incident playbook — and rehearse it.
Enforceable boundaries beat advisory rules. Build the wall, audit everything, and your agents can act autonomously without betting the host on their good behavior.
