We gave an autonomous AI agent a shell, an API key, and a budget for 270 turns. Here's what actually held it.
Most of the "agent security" discourse right now is code review — people reading each other's tool-call loops and arguing about prompt injection. Useful, but it skips the question a platform team actually has to answer before any of this ships.
You're about to give an AI agent a real shell, real credentials, and a budget. What exactly can it reach — and how do you know?
We ran the experiment instead of theorizing about it. We put a genuinely autonomous agent — shell execution, file I/O, ~90 tools — inside a locked-down GCP project and let it run for 270 turns with a task, a key, and money to spend. Then we watched what it did, and, more importantly, what it couldn't do. Here are the parts that surprised us.
Trap 1: a "deny-all" egress allowlist that returns HTTP 200 to example.com
You allowlist your LLM provider so the agent can actually work:
api.openai.com → 162.159.140.245, 172.66.0.243 (Cloudflare)
Then you test your deny-all from inside the sandbox with a site you didn't allow:
curl https://example.com → HTTP 200
That looks exactly like a broken firewall. It isn't. example.com resolves into the same Cloudflare /13 ranges as api.openai.com. The moment you allowlisted your provider by IP CIDR, you allowed every other Cloudflare-fronted site on the internet — which today is a large fraction of it.
The fix isn't a tighter CIDR (there isn't one — the ranges are shared). It's allowlisting by hostname through an egress proxy, not by IP. If your agent-sandbox story is "we allow the provider's IP ranges," your deny-all is decorative.
Trap 2: block the metadata server and you kill all DNS
The obvious hardening step: stop the agent from reaching the GCE metadata server at 169.254.169.254. An agent with a shell can curl its own OAuth token from there and — with the default service account — start creating VMs on your quota.
So you block it. And suddenly the container can't resolve anything, and you spend an hour convinced the image is broken.
On GCE, the metadata server is the DNS resolver. Block it naively and you've cut your own DNS. The correct shape is a port-53 carve-out to the metadata IP before the deny rule, so DNS survives while the token endpoint stays unreachable. The ordering is the whole trick, and you only learn it by breaking it.
Trap 3: the token you forgot the agent could mint
Related, and worse: even without a human handing it credentials, an agent with a shell and the default service account can mint an access token from the metadata endpoint and act as that identity. If that SA has project-level permissions — which is the default — your "sandboxed" agent can create infrastructure, read buckets, and spend money, none of which shows up in its transcript as a "dangerous tool call." It never used a tool. It used curl.
Containment here isn't a prompt or a tool policy. It's a bounded service account plus an egress rule that the agent's own root shell can't flush — because any iptables rule inside the guest can be flushed by the thing you're containing. The rule has to live in the VPC, outside the guest.
How we proved it held: the agent's own recon came back empty
The point of all this isn't the config — everyone ships Terraform. The point is proof. We ran a verify-isolation script: 10 checks with a hard exit 0/1 — off-allowlist egress blocked, metadata token unreachable from the container, service-account privilege bounded, no host bind mounts, no inbound path. CI-safe. The output pastes into a change ticket and ends the security conversation in one screen.
The most telling result wasn't ours. The agent, unprompted, ran its own reconnaissance script to map what it could reach. The network section of its report came back empty. It spent 270 turns inside a box and never knew the box was a box.
Why this matters now
Everyone is shipping agents. Almost nobody can answer the security team's one question with evidence rather than assurances. The gap between "we wrote a firewall" and "here's a script that proves what it can reach, exit 0" is exactly where these deployments stall — and it's a gap you can close in an afternoon if you know the three traps above.
verify-isolation.sh script, and a FINDINGS.md of the nine traps that cost real debugging time — ships as the Agent Sandbox Pack for GCP ($59).