Skip to content

Why Sandbox an Agent?

A sandbox runs a program with a boundary around it: it can touch only the files, hosts and settings you granted, and everything else is refused. The program still runs on your machine, as you — the boundary just decides what “as you” is allowed to reach.

You want one around a coding agent because an agent runs with your authority. Start it and it inherits everything your user account can do: read any file, use any credential, reach any host. That is not a misconfiguration — it is what a user account is. A sandbox narrows it to the job at hand.

flowchart LR
  agent["coding agent"] --> gate{"wardcell<br/>policy"}
  gate -->|allow| work["the project directory<br/>+ the API it needs"]
  gate -.->|deny + log| secrets["~/.ssh · ~/.aws · .env files"]
  gate -.->|deny + log| exfil["unlisted hosts"]

The real risk is not an agent deleting a file — that is loud and recoverable, and you notice. The quiet one is exfiltration:

A prompt injection in a README, a compromised dependency, or a plain model mistake can turn into a command that reads ~/.ssh/id_ed25519, ~/.aws/credentials or a project’s .env, and sends it to a host the attacker controls. A request to that host looks exactly like a request to a package registry. A key that leaves does not come back.

You cannot enumerate the hosts a secret must not go to — but you can usually name the three or four a tool legitimately talks to. That asymmetry is why wardcell’s network policy is an allowlist of destinations, and why a sandbox is the right shape for the problem: the credentials were never in reach, and a request to an unlisted host is refused and logged.

The failure is legible. You see the denial, decide whether it was legitimate, and either widen the policy or find out why your agent wanted your SSH key.

A sandbox is also a portability win. You write a policy once, as small .sbx fragments, and wardcell projects it onto whatever enforces it — Seatbelt on macOS and Bubblewrap on Linux today, Windows and cloud sandbox providers next. The same policy travels with your project and means the same thing on your laptop, a teammate’s machine and a CI runner, with no rewrite per platform.

A sandbox bounds reach, not intent. It does not help with:

  • Anything you explicitly grant. A policy that allows * allows everything.
  • A kernel or sandbox-mechanism bug. If Seatbelt or a user namespace has a hole, wardcell has one too.
  • A malicious policy. The policy root is trusted input.
  • Data the agent may legitimately read and then send to a host you allowed. If it may read your source and may reach api.example.com, it may send your source to api.example.com.

That last one is worth sitting with. A sandbox makes the blast radius of a mistake or an injection small and visible; it does not make an untrusted program safe, and it is not a substitute for reading what you run.