DEV Community

Harper Xu
Harper Xu

Posted on

Give Your AI Coding Agent a Sandbox Before You Give It Your Shell

A discussion thread that got a lot of attention on DEV this week asked a pointed question: we're handing AI agents more and more tools — what happens when the boundaries fail?

It's a fair thing to worry about, and it's not abstract. Any workflow where a model can write code and trigger execution is a workflow where a bad suggestion, a hallucinated flag, or a poisoned dependency becomes a real command on a real machine. The fix isn't to stop using agents. It's to stop running them in an environment where a mistake is expensive.

This post lays out a sandboxing pattern I think every developer using an AI coding assistant should adopt, plus a concrete container setup and a boundary test plan you can run in under an hour. The examples are illustrative — adapt them to your stack and verify them before trusting them.

The mental model: blast radius first, capability second

Most people evaluate an agentic coding tool by asking "what can it do?" The better first question is "what's the worst it can do from where it runs?" Concretely, an agent that can execute code should be assumed capable of:

  • Reading any file the runtime user can read (including ~/.ssh, .env, cloud credentials).
  • Writing anywhere the runtime user can write (including your git config and shell rc files).
  • Making network calls to anywhere the machine can reach.
  • Installing and executing arbitrary packages.

None of this requires a malicious model. It just requires a model that's confidently wrong one time out of a hundred. So the goal of the sandbox is simple: make all four of those abilities boring.

A minimal sandbox with Docker

Here is a starting Dockerfile for an isolated agent workspace. It's deliberately restrictive and intentionally unglamorous:

FROM node:20-slim

# Non-root user; the agent never runs as root.
RUN useradd -m agent

# Only the project directory is writable.
WORKDIR /workspace
RUN chown agent:agent /workspace

USER agent

# No network by default — enable explicitly per-run if needed.
# Run with: docker run --network none -v ./project:/workspace agent-sandbox
Enter fullscreen mode Exit fullscreen mode

Key properties and why they matter:

  1. Non-root user. A surprising amount of damage requires root. Don't grant it.
  2. Mounted project only. The agent sees the repo, not your home directory. Credentials stay outside the mount.
  3. --network none by default. If the agent needs to npm install, run a separate, explicit "dependency step" with network on, then run the agent's edit/test loop with network off. This single habit blocks entire categories of supply-chain and exfiltration surprises.
  4. Ephemeral containers. docker run --rm means every session starts clean. State is an attack surface too.

Where free compute actually helps this pattern

The obvious objection: spinning up isolated environments per task sounds expensive, or at least annoying, if you're paying per hour for a dev machine.

This is where I've found it handy that MonkeyCode — an AI coding assistant — offers free access to its models and a free server option to run on. That combination maps neatly onto the pattern above: the model side costs nothing to experiment with, and the server side can act as the sacrificial environment — a machine that isn't your laptop and doesn't hold your personal credentials — where the agent's commands execute.

Disclosure: This article was prepared as part of MonkeyCode's product outreach.

To be clear about what I'm not claiming: I haven't benchmarked MonkeyCode's models against anything else, and I can't speak to quotas, hardware specs, or how long the free tier lasts. The point of this article stands with any tool — if your agent runtime is free or cheap, use that fact to make the runtime disposable. If it's your daily-driver laptop, containerize it yourself with the Dockerfile above.

A boundary test plan (run this before trusting the setup)

Don't assume your sandbox works. Test the boundaries the same way you'd test auth on an API. Here's a checklist you can execute in one sitting:

# Test Pass condition
1 Agent asked to read /etc/shadow or host home dir Fails with permission error
2 Agent asked to curl an external URL Fails when network is disabled
3 Agent asked to write outside /workspace Fails; host filesystem untouched
4 Agent asked to install a package at runtime Blocked or confined to the ephemeral container
5 Agent runs rm -rf on its own workspace Host unaffected; container discarded
6 Secrets scan of the container image No tokens, keys, or .env files present

Tests 1–3 catch misconfiguration. Tests 4–5 catch overconfidence — yours, not the model's. Test 6 is the one everyone skips: bake no credentials into the image, and pass any needed secrets in explicitly, per-run, with the narrowest scope possible.

A quick automated version of test 2, for example:

docker run --rm --network none agent-sandbox \
  sh -c "curl -sS --max-time 3 https://example.com" \
  && echo "FAIL: network is open" || echo "PASS: network blocked"
Enter fullscreen mode Exit fullscreen mode

Add equivalents for the other rows to CI or a make check-sandbox target, and re-run them whenever the image or the tool config changes.

Limitations, honestly

  • Sandboxing is not alignment. A sandbox limits damage; it doesn't make the agent's code correct. You still review diffs before merging. Always.
  • Network-off breaks real workflows. Package installs, fetching docs, hitting test APIs — you'll need a deliberate, audited network-on step, which is friction. That friction is the price of the boundary.
  • A free server is still someone else's machine. Don't point an agent at proprietary code or customer data on any third-party environment without understanding the provider's data handling. Read the terms; when in doubt, sandbox locally.
  • Container escapes exist. For ordinary dev work, a non-root container with no network is a strong boundary. For hostile-input scenarios, look at stronger isolation (microVMs like Firecracker, gVisor, separate hardware).

Who should skip this

If your agent usage is purely "suggest a snippet in my editor that I paste myself," you already have a human sandbox — you. This pattern is for workflows where the tool executes code, runs tests, or touches a shell. And if you're working with regulated data, treat this article as a starting point for a conversation with your security team, not a compliance plan.

Takeaway

The answer to "what happens when the boundaries fail?" is: whatever your environment lets happen. So make the environment boring. Non-root, no network, one mounted directory, ephemeral everything, and a six-row test plan you actually run. If you want a low-cost place to try the pattern, MonkeyCode's free model access and free server option are an easy on-ramp for a disposable agent workspace — but the pattern itself belongs in your workflow no matter which assistant you use.

Top comments (0)