A Dev Container for Your AI Coding Agent
Giving an agent terminal access on your laptop is a bad trade. A dev container gives it a real shell, a real toolchain, and a blast radius you chose in advance.
An AI coding agent is far more useful with a shell than without one, and far more dangerous on your laptop than in a box. A dev container is the cheapest way to have both: the agent gets a real terminal, real installs and real test runs, and the worst case is a container you delete. This is a working setup rather than a survey, with the specific decisions that matter called out.
Start from what you are protecting
Three things, in order of how badly they go wrong.
Credentials. Cloud CLI profiles, SSH keys, browser session cookies, the
.envfiles in every other project on your machine.Other repositories. An agent asked to search for a symbol will happily walk up out of your project directory if nothing stops it.
The network. Not because the agent is malicious, but because a fetched dependency can be, and a container with unrestricted egress is a fine place to exfiltrate from.
A dev container addresses all three with one config file, which is why it beats trying to remember which flags to pass each time.
A config that works
{
"name": "agent-sandbox",
"image": "mcr.microsoft.com/devcontainers/base:ubuntu-24.04",
"workspaceFolder": "/work",
"workspaceMount": "source=${localWorkspaceFolder},target=/work,type=bind",
"mounts": [],
"runArgs": [
"--cap-drop=ALL",
"--security-opt=no-new-privileges",
"--memory=4g",
"--pids-limit=512"
],
"containerEnv": {
"HOME": "/home/dev",
"GIT_TERMINAL_PROMPT": "0"
},
"remoteUser": "dev",
"features": {
"ghcr.io/devcontainers/features/node:1": { "version": "22" },
"ghcr.io/devcontainers/features/python:1": { "version": "3.12" }
},
"postCreateCommand": "npm ci && npm run build"
}The empty mounts array is the point of the whole file. The default templates helpfully mount your SSH agent, your git config and sometimes your cloud credentials. Delete all of it. If the agent needs to push, it can hand you a branch and you push from outside.
The four decisions that matter
One repository, bound at /work
Bind only the project directory. Not the parent, not your home. An agent that cannot see your other repositories cannot accidentally edit them, and does not need a rule telling it not to. Related discipline: how to stop an AI coding agent from editing unrelated files.
Drop capabilities, cap resources
--cap-drop=ALL and --security-opt=no-new-privileges cost nothing and remove a category of container escape. The memory and PID limits are there for a duller reason: agents write infinite loops, and an unbounded fork bomb inside a container still takes your machine down.
Restrict egress
The default is unrestricted outbound, which is convenient and wrong. Put the container on a network where only your package registry, your git host and your model provider are reachable. In Docker Compose terms that means an explicit network plus a proxy rather than the bridge default. If a build suddenly needs an unexpected host, you want to know.
Credentials by injection, never by mount
If the agent genuinely needs an API key for an integration test, pass a scoped, short-lived one through containerEnv at run time. Never mount the file that holds the real one. The difference is that a leaked scoped key is a rotation, and a leaked profile directory is an incident.
What the agent should find waiting for it
A sandbox that cannot build the project is worse than no sandbox, because the agent will spend twenty steps trying to fix the environment. Bake it into postCreateCommand so the container arrives ready:
Dependencies installed and the project building.
The test suite runnable with one command, and that command written down in your agent instructions file.
A seeded local database if you use one, so the agent never reaches for a shared instance.
Linters and formatters available, so style corrections happen locally rather than in CI.
That last set is what turns the container from a cage into a workbench. The agent gets a fast, unambiguous check on its own work, which is the single highest-leverage thing you can give it. See our AI coding tools pillar for where those commands belong.
When a container is not enough
If the agent needs to reach a staging environment, the container boundary stops helping and you are back to scoping credentials properly. running an AI coding agent in CI and safe terminal access cover that case. For the general isolation model beyond dev work, see how to sandbox an AI agent.
Frequently asked questions
Does this work with any agent?
Any agent that runs as a CLI process does, because it just runs inside the container like any other tool. Agents that run as a hosted service with their own sandbox already have an equivalent, and the interesting question there is what their sandbox mounts.
Is a virtual machine better?
Stronger isolation, slower loop. For day-to-day coding work the container is the right trade. For anything running untrusted code you did not write, use the VM.
Will the agent notice it is sandboxed?
Yes, and that is useful. Agents behave more conservatively when a command fails with a permission error than when it silently succeeds against the wrong system.
What about git credentials?
Leave them out. Let the agent commit locally on a branch, then review and push from your host. It also gives you a natural review checkpoint you would otherwise skip.
How did this land?
About the author

Developer Advocate
Steve builds something with Swarmz every week and writes up what worked, what broke, and what he'd do differently. Tutorials and hands-on guides are his lane.


