The hard part of AI coding is not getting a model to write code. The hard part is letting it run useful commands without quietly handing it your whole machine.
That tension shows up fast in real workflows. The agent wants to install packages, run tests, inspect the repository, build containers, and maybe hit an internal service. You want all of that to happen inside clear boundaries so a bad prompt, a confused tool call, or a risky dependency install does not spill across your laptop or production-adjacent environment.
The fix is not one magical sandbox. It is a layered setup: isolate execution, scope filesystem access, constrain network reach, and make sensitive actions require a different lane than routine coding work.
The threat model is boring, and that is why it matters
Most failures here are not movie-plot jailbreaks. They are ordinary engineering mistakes with better tooling behind them.
- modify files outside the intended repo
- leak secrets from shell history or local config files
- install packages with post-install scripts that touch the host
- run expensive or destructive commands because the task description was ambiguous
- persist credentials in places a later task can read
- open a network path to systems that were never part of the assignment
Start with the right mental model
A container is not a complete security strategy. It is just one boundary.
For practical AI coding work, think in four layers:
- Workspace scope — what files can the agent read or write?
- Runtime isolation — what process boundary contains the code execution?
- Network policy — what hosts can the agent reach?
- Approval path — what still requires a human or a separate trusted workflow?
A good default: dev container plus narrow mounts
For many teams, the best first step is a repeatable development container with a small blast radius. The Development Containers spec is useful because it standardizes the environment around the repository instead of around one engineer's laptop.
- Mount the target repository as writable
- Mount only small caches if performance really needs them
- Keep out home directories, SSH keys, cloud credentials, and unrelated projects
- Avoid Docker socket access unless nested builds are genuinely required
Read-only mounts are underrated
Docker bind mounts are writable by default. That means processes in the container can change the host filesystem unless you explicitly mark the mount readonly or ro.
docker run --rm \
--mount type=bind,src=$PWD,dst=/workspace \
--mount type=bind,src=$HOME/.npm,dst=/home/dev/.npm,readonly \
--mount type=bind,src=$HOME/.gitconfig,dst=/home/dev/.gitconfig,readonly \
my-agent-imageIf a mount exists only to make the environment feel familiar, it is probably too generous.
Treat network access as a separate permission
For coding agents, network access is often the real privilege. Package installs, test services, GitHub APIs, and cloud endpoints should not all live behind one blanket allow rule.
- No network for local editing and static analysis
- Registry-only for dependency installation
- Allowlisted outbound for GitHub APIs or specific internal test services
- Never ambient access to production from the same environment that executes untrusted code
MicroVMs are worth it when the agent gets more power
Regular containers still share the host kernel. That is why stronger isolation layers exist. Firecracker uses lightweight microVMs with a reduced device model, while gVisor inserts an application kernel between the workload and the host kernel.
Reach for stronger isolation when the agent runs arbitrary repo code, installs third-party dependencies often, serves many users, or has access to systems you care about.
Never pass the host Docker socket casually
Mounting /var/run/docker.sock into a coding environment can effectively bypass the original container boundary. If the agent needs image-build capability, prefer a nested daemon, rootless tooling, a remote build service, or a microVM-backed sandbox with its own runtime.
Build two lanes: routine work and sensitive work
Lane 1: routine coding
- reading and editing repo files
- linting, formatting, type checks, and unit tests
- short-lived environment with narrow mounts and limited egress
Lane 2: sensitive actions
- deploys, releases, infrastructure changes, and credentialed publishing
- separate executor or workflow
- explicit approval boundary and audited credentials
Make the sandbox disposable
Disposable environments reduce stale credentials, strange one-off fixes, and container drift. Persist only what you deliberately need, such as package caches.
A minimal policy that teams can actually maintain
AI coding sandbox policy
- Mount only the target repo as writable.
- Mount caches read-only unless writes are required for performance.
- Do not mount the host home directory.
- Do not mount SSH agents, cloud config, or Docker socket by default.
- Default network mode is off; enable only the minimum required egress.
- Use a separate executor for deploys, releases, and infrastructure changes.
- Destroy the sandbox after each task unless a human explicitly keeps it.What this looks like in practice
{
"name": "repo-agent",
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"workspaceFolder": "/workspace",
"features": {
"ghcr.io/devcontainers/features/node:1": {
"version": "22"
}
},
"mounts": [
"source=${localWorkspaceFolder},target=/workspace,type=bind",
"source=${localEnv:HOME}/.npm,target=/home/vscode/.npm,type=bind,consistency=cached"
],
"postCreateCommand": "npm ci",
"remoteUser": "vscode"
}Then tighten it before handing it to an agent: make extra mounts read-only where possible, strip credential-bearing files, disable network unless setup truly requires it, and keep approvals outside the container for sensitive actions.
Common mistakes
- Confusing reproducibility with isolation
- Over-mounting for convenience
- Mixing package installation and deploy power
- Keeping sandboxes alive forever
Final takeaway
Useful AI coding does not require giving the agent a blank check. The winning pattern is layered: reproducible dev environment, narrow writable scope, read-only everything else, explicit egress rules, and a separate path for high-trust actions.
If your current setup mounts half your laptop into the agent so it can feel comfortable, that is not velocity. That is unsecured convenience dressed up as workflow.