# Secure agents: architecture and sandboxing

> Source: <https://katelynlesse.com/blog/secure-agents-architecture-and-sandboxing>
> Published: 2026-09-13 00:00:00+00:00

[Back](/)

# Secure agents: architecture and sandboxing

If you're building and running production agents, security is likely one of your most important requirements. You probably need to prove to internal teams and to your customers that your agents can't take any harmful actions and that data & credentials remain protected. The incidents the industry has seen in the past year have largely been caused by a few problems - prompt injection, insecure credential access, and open network access.

The industry has learned a lot together about avoiding these incidents and building secure agents, and it turns out it's simpler than you might think. It mostly comes down to one major architecture decision and a couple important sandbox configuration decisions.

## Split the brain from the hands

An agent is a harness (loop that calls a model API, calls tools, and gets user input), a sandbox to execute generated code and shell commands, stored session state, and credentials like model API keys, git tokens, and OAuth tokens for SaaS tools the agent can call on a human's behalf.

When agents were running mostly locally and not taking much autonomous action, nobody really thought that hard about how to architect them, and they were mostly just shoved together onto a laptop or other machine like a sandbox. The problem that emerged is that untrusted content ends up in the sandbox with the agent. Agents clone repos, read websites, parse tool output, and even install packages. Any of that can end up including text that a model might follow as instructions (prompt injection) or code that will end up running. Which is scary on its own, and add in the fact that a credential inside the sandbox with your agent is a credential that the agent can read, use, or send off somewhere - even scarier.

The architectural fix that the industry is largely converging on is relatively simple: split the brain from the hands. The harness, session state, and credentials should live outside the sandbox on durable infrastructure that you trust. Then the sandbox just becomes a tool the agent can use for execution. Importantly, when code in the sandbox wants to talk to an external service, the request should go out through an egress (outbound) proxy, which injects any necessary credentials on the way out, scoped to just that specific destination. The sandbox could hold a placeholder that the proxy replaces with the real cred. Same idea for handling users' OAuth tokens for their MCP tools. They should go in a vault-like service next to the harness and a proxy injects them when the agent calls those tools.

My team learned this through encountering challenges and iterating, which I [wrote about](/blog/you-cant-avoid-the-hard-part) previously. It's been good to see much of the industry converge on some version of this split over the last year.

If you choose to run a whole agent inside a box, it's just really hard to get equivalent security properties. Secrets have to enter the box, so you're relying on redaction and it's not really foolproof. You've got a model API key hanging out with untrusted code. Your kill switch is basically inside the thing you're trying to kill. With brain/hands split architecture, these properties end up structural.

## Sandbox config

Brain/hands split architecture is a lot of the battle. But the sandbox where "untrusted" things are happening still needs the right config to make it safe and sound (ever wonder why it's called a sandbox?).

First there's isolation, and you can choose between 4 levels, weakest to strongest. Containers on the weak end share the host machine's operating system kernel, and shouldn't be treated as a security boundary for untrusted code. A user-space kernel like gVisor gives each sandbox its own kernel implemented in software, so untrusted code can never touch the host kernel directly, which is a nice step up. MicroVMs (e.g. Firecracker) go even further: each sandbox is a small virtual machine that gets its own kernel. It's kept separate by the CPU's virtualization hardware, and they can still start fast enough that you can spin them up on demand. Full VMs or dedicated hosts are of course real hardware separation with no other tenants on the machine, which some regulated workloads might need.

If you're optimizing for security and practicality, you most likely want microVMs. The boundary is physical, enforced by the CPU's virtualization support. A user-space kernel is also a solid choice, just with some performance tradeoffs. Running untrusted code in plain containers is the thing you likely want to avoid. But whichever you pick, a step up in security is to make sandboxes ephemeral and treat them like cattle instead of pets: spawn them when you need them, have hard limits on time and resources, and destroy them at the end. This means you don't leave anything behind for an attacker. Plus, anything that goes wrong is contained to just that session.

Next is egress, which is the outbound network configuration. If untrusted code in a sandbox runs while the network is open, it can send things out, which can be as innocuous as reading a web page or as bad as uploading a buggy package somewhere. So you should default-deny outbound traffic through a proxy, and have a limited allowlist for what your tasks will actually need to access. Be as specific as you can about hosts and HTTP methods, and DNS should be closed off too. Something to consider is doing dependency installs at the start of a session, and then lock everything down before the agent starts doing its work.

Lastly, you need monitoring and a kill switch. You should log tool calls, commands, and network access to somewhere the sandbox can't access, so untrusted code can't go turn your logging off. And build a kill switch that you can hit mid-session that will actually stop anything in your fleet on the spot.

If you're building agents and want to make them secure, first make the easy architecture choice - keep your harness, state, and credentials out of the box. Then configure the box well - strongly isolated, closed by default, and monitored from outside.
