Sandboxing & Code Execution

A15
Concepts · Agentic AI Explained

Sandboxing & code execution.

Giving an agent the ability to run code is the single largest capability jump available to you, and the single largest expansion of what can go wrong — because the code is written by a system that can be argued into writing the wrong code. This entry covers why code execution is worth it anyway, what a sandbox is actually defending against, and the axes of isolation that matter in practice.

STEP 1

Code is the universal tool.

Most tools are narrow: one function, one schema, one action. Code execution is different — it is a single tool that subsumes an unbounded set of them. That buys three things:

  • The long tail without the tool surface. Parse this odd file format, reshape this data, compute this statistic, rename these two hundred files. Writing a dedicated tool for each is impossible; a runtime handles all of them.
  • Real computation instead of predicted computation. A model asked to do arithmetic predicts a plausible answer. A model asked to write and run the arithmetic gets the actual one. Anything deterministic and checkable — math, sorting, date logic, format conversion — is better delegated to a runtime than performed in the weights.
  • Keeping bulk out of the context window. Code can fetch a million-row file, filter it, and return four numbers. Without execution, all million rows would have to pass through the context window to be reasoned over — slower, costlier, and worse.

This is why nearly every capable coding and data agent has a shell or a Python runtime at its center. The capability is not optional for that class of work; the isolation is what makes it safe to have.

STEP 2

What you are actually defending against.

The instinct is to think of this as a malicious-user problem. It mostly is not. Three distinct sources of bad code, and only one involves a hostile human:

  • Model error. The agent writes a delete with the wrong path, a loop that never ends, a migration against the wrong database. No adversary required — just an ordinary mistake with root-shaped consequences.
  • Prompt injection. Untrusted content enters the loop — a web page, an email, a repository file, a tool result — carrying instructions, and the agent writes code that follows them. This is the case where "the user is trusted" provides no protection at all, because the attacker is not the user.
  • Untrusted code and data pulled in at runtime. A dependency the agent installs, a script it downloads, a file it was handed. The agent executes it faithfully, and whatever it does is now running inside your boundary.

The load-bearing idea: agent-written code is untrusted code, always. Not because the model is adversarial, but because its output is a function of inputs you do not fully control. Treat the runtime the way you would treat a public code-execution endpoint — because in the presence of injection, that is close to what it is.

STEP 3

The five axes of isolation.

"Sandboxed" is not a boolean. It is a set of independent decisions, and teams routinely get two of them right and leave the rest wide open:

  • Filesystem. What can it read, what can it write? The default should be a scratch workspace plus explicitly mounted inputs — not the host filesystem with the agent politely instructed to stay in its lane.
  • Network egress. The most under-configured axis, and the one that turns a contained mistake into a breach. With unrestricted egress, any data the sandbox can read, it can send. Deny by default and allow-list the hosts the task genuinely needs.
  • Credentials. What secrets are reachable from inside? Ambient environment variables, cloud instance metadata, a mounted SSH key, a logged-in CLI — all of these are credentials the executed code inherits for free. The strongest pattern keeps secrets outside the sandbox entirely: the agent asks for an authenticated action, and a process you control performs it.
  • Compute and time. CPU, memory, disk, and a wall-clock ceiling. This is mostly about runaway loops and cost, not attack — but an agent that can spend unbounded compute is its own kind of incident.
  • Lifetime. Ephemeral per-run, or persistent across a session? Persistence is genuinely useful — installed packages, intermediate files, working state — and it is also how something planted in one run reaches the next. Default to ephemeral, and make persistence a deliberate choice.

The mechanisms form a spectrum, roughly in increasing order of strength and cost: running in the host process (no isolation — do not), a subprocess as a restricted user, a container, a microVM, and a hosted execution service that owns the boundary for you. Container-level isolation is the common floor; anything running genuinely untrusted code wants a hardened boundary above it.

STEP 4

Four rules, and the limit of the whole idea.

  • No ambient credentials inside. If the sandbox can reach a secret, assume executed code can exfiltrate it. Broker privileged actions from outside the boundary rather than handing the key across it.
  • Sandbox output is untrusted input. Whatever the code prints comes back into the agent loop as an observation the model will act on. A sandbox stops code from touching your systems; it does nothing to stop the text it produces from steering the next step.
  • Log what ran. The executed code, its arguments, and its output are the trace you will need when something surprising happens — and they are the only durable record of what the agent actually did, as opposed to what it said it did.
  • Isolate per tenant and per trust boundary. One shared long-lived sandbox across users is a cross-contamination path, whatever the process-level isolation looks like.

A sandbox bounds what the agent can reach; it says nothing about whether the actions it is allowed to take are the right ones. An agent legitimately permitted to send email can still send the wrong email from inside a perfect sandbox. Isolation handles the blast radius of unintended capability; approval gates and scoped permissions handle the consequences of intended capability. You need both, and they are not substitutes for each other.

The sandbox & isolation patterns deep-dive covers the mechanisms in depth, the sandboxing & execution playbook covers the coding-agent case specifically, and data-exfiltration risks covers the egress problem that isolation alone does not solve. For the related case where the agent drives a screen rather than a shell, see computer use.