September 6, 2026 · Konuke
Sandboxing agents: runtime isolation for workers that run code and use computers
The most capable agents don't just call tidy APIs—they run shell commands, execute generated code, and click around real browsers. That power lives in an execution environment, and if that environment is your laptop or a long-lived production box, one hijacked agent has a shell on your infrastructure. Here is how to give agents a sandbox: ephemeral, network-scoped, least-privilege runtimes where the worst a wrong decision can do is destroy a container you were going to throw away anyway.
Most agent security writing stops at the API boundary. Scope the credentials, design safe tools, gate the irreversible actions, and you have covered the agent that only ever calls well-behaved functions. But the agents that create the most value are rarely that tidy. A coding agent that actually ships work needs to run your test suite, install dependencies, and execute code it just wrote. A research agent that can use a computer needs a real browser it can click through. A data agent worth having writes and runs queries and scripts against messy files.
The moment an agent can run arbitrary code or drive a real machine, the interesting question is no longer "which functions can it call?" It is "where does that code execute, and what can reach out from there?" That place is the runtime—and if the runtime is an engineer's laptop, a shared CI runner, or a long-lived production VM with ambient cloud credentials, then a single prompt injection or one confidently-wrong command is no longer a bad paragraph. It is a shell on your infrastructure.
This post is about the layer underneath the action layer: the sandbox. Not sandboxing as a buzzword, but as a concrete engineering decision—ephemeral, isolated, network-scoped execution environments where autonomy produces useful work instead of a breach you get to explain later.
Why the runtime is its own attack surface
It is tempting to fold execution into the tool discussion. Both matter, but they fail differently, and conflating them hides risk.
The action layer is about the verbs you hand an agent: refund_order, send_email, merge_branch. You control those functions, so you can make them narrow, previewable, and reversible. The runtime is about the ground the agent stands on while it decides which verbs to call and executes anything in between. A run_code or execute_shell tool is deceptively small in your tool list and effectively unbounded in practice: it is a single verb that grants the agent every verb the operating system offers.
That is the trap. Teams spend weeks scoping a delete_customer tool and then hand the same agent an unrestricted bash tool "so it can run the tests," never noticing they just re-granted everything they carefully took away. The runtime quietly becomes the widest permission the agent has.
Three properties of the environment decide how bad a mistake can get:
- What credentials are ambient. A cloud VM with an attached instance role, a shell with
~/.aws/credentials, a checkout with a long-livedGITHUB_TOKENin the environment—an agent that can run code can read all of it. Ambient credentials are the difference between "the container died" and "someone exfiltrated our secrets." - What the environment can reach. If the runtime has open outbound network access, injected instructions can
curlyour data to an attacker or pull down a second-stage payload. Egress is the exfiltration path that most teams never think to close. - What survives the run. A long-lived environment accumulates state: cached credentials, poisoned files, a modified shell profile that runs on the next invocation. Persistence turns a one-time compromise into a foothold.
Sandboxing is the discipline of driving all three toward their safe extreme: no ambient credentials, no unnecessary egress, nothing that survives the run.
The blast-radius test
Before the patterns, one principle to make the rest concrete. For any environment where an agent runs code, ask:
If this exact runtime were fully controlled by an attacker for the duration of one run, what would we lose?
If the honest answer includes production data, standing cloud credentials, the ability to reach internal services, or persistent changes to a shared machine, the environment is too powerful for autonomous execution. The goal is an answer you can shrug at: "They'd get a throwaway container with a shallow clone of one repo, no secrets, and network access to exactly three package registries. Then it gets destroyed."
That is not paranoia. Assume the agent will, at some point, execute instructions written by an attacker—because the moment it reads untrusted content, it can be hijacked. The sandbox is what makes that assumption survivable instead of catastrophic.
Pattern 1: Ephemeral, disposable environments
The single highest-leverage control is making the runtime disposable. Every agent run (or every session) gets a fresh environment—a container, microVM, or ephemeral cloud sandbox—provisioned from a known-good image and destroyed at the end.
Disposability buys you three things at once:
- No persistence for attackers. A poisoned file, a backdoored dependency, an edited startup script—none of it matters if the whole environment is torn down and rebuilt next time. Compromise cannot compound across runs.
- Reproducibility. A fresh environment from a pinned image means "works on the agent's machine" actually means something. This is the same reproducibility your evals and regression suites depend on—non-deterministic workers are hard enough without non-deterministic runtimes underneath them.
- A clean containment story. When something goes wrong, "destroy the environment" is a real, fast, complete kill switch for the runtime. You are not hunting for what an agent left behind on a shared box.
The anti-pattern is the pet: one long-lived agent VM that every run reuses because provisioning felt slow. Pets accumulate state, drift from their image, and become the exact foothold you were trying to avoid. Treat agent runtimes as cattle—ideally cattle that live for one task and then die.
Pattern 2: Strong isolation boundaries
Disposable is necessary but not sufficient; while it is alive, the environment has to actually contain the workload. Isolation is a spectrum, and the right rung depends on how untrusted the code is.
- Process/user isolation (a non-root user, dropped capabilities, rlimits) stops casual mistakes but not a determined attacker sharing a kernel.
- Container isolation (namespaces, cgroups, seccomp/AppArmor profiles, read-only root filesystems, no
--privileged, no host socket mounts) is a reasonable default for code you semi-trust. The classic mistake is mounting the Docker socket into the agent's container "for convenience," which is equivalent to handing it root on the host. - VM-level isolation (microVMs like Firecracker, or per-run cloud sandboxes) gives you a hardware-backed boundary and is the right call when an agent executes genuinely untrusted, internet-derived, or user-supplied code.
You do not need the strongest boundary everywhere. You need to match the boundary to the trust level of the code and never let convenience quietly downgrade it. A good rule: the less you can predict what will run, the stronger the wall around it—and code an agent wrote after reading a web page is, by definition, unpredictable.
Pattern 3: Default-deny network egress
If you adopt only one control from this post, make it this one. Most sandboxing conversations obsess over inbound isolation—stopping code from escaping the box—while leaving outbound access wide open. But for a business agent, egress is the whole ballgame: it is simultaneously the data-exfiltration path and the second-stage-payload path. An agent with your data and an open network can send that data anywhere; an agent that can fetch arbitrary URLs can pull down whatever an attacker wants it to run.
Start from deny-all outbound and add back only what the task provably needs:
- An allowlist of destinations—the specific package registries, the internal API it is meant to call, the git remote—rather than open internet.
- A proxy or egress gateway that logs every outbound request, so exfiltration attempts show up in your audit trail instead of vanishing.
- No route to your internal network unless the task requires one specific service, in which case expose that service and nothing else. A sandbox that can reach your whole VPC is not a sandbox.
Yes, allowlists cause friction; an agent will occasionally need a host you did not anticipate. That friction is the control working. Handle it by making it easy to request a new allowed destination through a reviewed change—not by leaving egress open because closing it was annoying.
Pattern 4: No ambient credentials
An agent that runs code can read every environment variable, every file in the home directory, and every token mounted into the container. So the sandbox must contain as little worth stealing as possible.
- Keep long-lived secrets out of the runtime entirely. No standing cloud credentials, no personal access tokens baked into the image, no
.envfull of production keys sitting in the working directory. - Broker access instead of granting it. When the agent legitimately needs to act on an external system, route that action through a separate, trusted broker—a small service that holds the real credential, enforces policy, and exposes only a narrow, audited operation to the sandbox. The agent asks the broker to do the thing; it never holds the key. This keeps the powerful, permanent credentials on the other side of the isolation boundary from the untrusted code, and it is the natural home for the least-privilege identity work you have already done.
- Use short-lived, scoped tokens when a credential must be present—minted per run, expiring in minutes, scoped to exactly the resource in play. A leaked token that is already dead is a non-event.
The mental model: the sandbox is untrusted, so nothing of lasting value should ever be inside it. Value lives behind the wall, reachable only through narrow, logged doors.
Pattern 5: Resource limits and a budget
Not every runtime failure is an attacker. Sometimes an agent simply loops on a broken tool, forks bombs by accident, or fills a disk with logs. And sometimes it does spin up expensive resources because an injected instruction told it to. Either way, an unbounded runtime is an unbounded bill and an availability risk.
Cap the obvious dimensions: CPU and memory (cgroups), disk, wall-clock execution time per run, and process count. Pair the environment-level limits with the economic ones—an agent that can provision cloud resources needs a spending ceiling, which is exactly the kind of risk your ROI and cost model should already be pricing in. A runaway that hits a hard wall and dies is a line in a log. A runaway with no wall is an incident.
Pattern 6: Make the sandbox observable
An isolated environment that logs nothing trades one blind spot for another. The sandbox is where the agent's intentions become actions, which makes it the richest possible source of evidence—if you capture it. Instrument the runtime the way you would instrument any agent:
- Commands executed and their exit codes—the closest thing you have to the agent's actual behavior.
- Outbound network requests, via the egress proxy, so an exfiltration attempt is a logged, alertable event rather than a silent success.
- Filesystem changes worth diffing, so you can see what a run actually produced or tampered with.
- The link back to the trigger: which task, which prompt, which inputs led to this run, so that when you reconstruct an incident you are not guessing.
Send these to a store the sandboxed workload cannot reach or rewrite. Logs the agent can edit are not audit logs.
Where this fits with everything else
Sandboxing is not a replacement for the rest of the stack—it is the floor the rest stands on, and it is most powerful in combination:
- Least-privilege identity decides what an agent may touch; the sandbox ensures a compromise of the runtime cannot quietly widen that.
- The action layer makes individual actions safe and reversible; the sandbox contains everything the agent does between those actions.
- Prompt-injection defenses reduce how often the agent is hijacked; the sandbox decides what a successful hijack actually costs.
- Observability and an incident response plan turn "destroy the environment" into a real, rehearsed kill switch.
Layered, these are the difference between an agent program that can safely run code and one that only dares call read-only APIs. And running real code is where a lot of the value is.
Why this is table stakes for agent-driven work
Here is the part that makes sandboxing strategic rather than merely defensive. The whole premise of agent-driven development is that agents do real, verifiable work: write code, run it, see it fail, fix it, prove it passes. That loop is only honest if the agent can actually execute—and it is only safe if execution happens somewhere disposable. The teams that will run fleets of agents in a few years are the ones building the muscle now to give every agent a clean, isolated, credential-free room to work in and then throw that room away.
This is the same trajectory every powerful technology follows. We did not stop running untrusted code from the internet; we invented browsers with sandboxes, containers, and CI runners so we could run it safely. Autonomous agents are the next thing that runs untrusted-ish code constantly, on your behalf, at scale. Ephemeral, isolated runtimes are how that becomes ordinary instead of alarming—the same way always-on automation already feels as normal as nightly CI. "Where does the agent run code?" will be as routine a design question as "where does this service get deployed?" is today.
Where we can help
If you are moving agents from "call a few APIs" to "actually run code and use computers," the runtime is where security either becomes real or becomes theater. We help teams design ephemeral, network-scoped, credential-free execution environments—and the observability and kill switches around them—so autonomy stays defensible. Tell us about your setup or read the consulting offer.
Related tools: Agent Policy as Code • Always-On Agent Watchdog • Incident Runbook Generator
Want this as a workshop or rollout plan?
Book a 30-minute fit call or send context via the form—we respond within one business day.