What you are actually granting
A tool that can run commands and edit files unattended has, by default, whatever you have. Read the sentence slowly, because the implications are usually not thought through at the moment somebody clicks allow.
It can read every file your user can read, which includes ~/.aws/credentials, ~/.ssh/id_ed25519, .env files in every project you have ever cloned, and your browser’s cookie store. It can run any command, which includes rm, git push --force, terraform apply, psql against whatever DATABASE_URL points at, and curl to anywhere. It can install packages, which executes code from the internet. And it will do all of this from an instruction it interpreted, which may have come from a file it read.
That last point matters and is easy to miss. If the agent reads an issue, a README, a dependency’s documentation or a web page, text inside that content can look like an instruction. This is prompt injection, it is unsolved, and it means the boundary you need is a real one (a sandbox) rather than a promise about behaviour.
The three levels of confinement
Level 1: a clean tree and a diff you read. The minimum. Commit first, let it work, read git diff, accept or git checkout .. This protects the repository and nothing else.
Level 2: a container or dev container. The agent runs inside a container with the project mounted and nothing else. It cannot see your home directory, your SSH keys or your cloud credentials, because they are not in the filesystem it has.
// .devcontainer/devcontainer.json
{
"image": "mcr.microsoft.com/devcontainers/python:3.12",
"mounts": [],
"remoteEnv": { "AWS_PROFILE": "", "GITHUB_TOKEN": "" },
"postCreateCommand": "pip install -r requirements.txt"
}Docker and Podman are free; Podman runs rootless, which is a further layer. This level takes twenty minutes to set up once and is where most people should be.
Level 3: a disposable VM or a remote sandbox, with no network except a package registry. For running code you have not read at all, or for anything touching a system you cannot afford to have touched.
Credentials: the part people get wrong
Sandboxing the filesystem is pointless if the environment carries a token that can deploy.
- Separate identities. A git identity for agent commits, with push rights to branches and none to
main. When something odd appears in the history you know immediately which it was. - Read-only database credentials by default. A separate role,
GRANT SELECTonly, pointed at a restored snapshot rather than production. Most exploration needs nothing more. - No cloud credentials in the environment at all unless the specific task needs them, and then scoped and short-lived.
- Never
.envin the working directory during an agent session. Move it, or use a secret manager that requires an explicit fetch.
The test to apply: if this session did the worst thing it could do, what would that be? If the answer involves production data or a deployment, the confinement is not yet right.
Allow and deny lists
Most agentic tools support pre-approving some commands and blocking others. Configure it, because the default of approving each prompt individually degrades into approving everything within an hour: the prompts arrive faster than judgement can be applied to them.
A sound starting point:
- Auto-allow:
ls,cat,rg,git status,git diff,git log, the test command, the type checker, the linter, the formatter. - Always ask: any
git push, any package install, any network call, any file write outside the project, anything withsudo. - Always deny:
rm -rf,git push --force, anything touching~/.sshor~/.aws, anything naming a production host.
The principle is that the read-only operations, which are the vast majority, should be silent, so that a prompt actually means something when it appears. A permission dialogue that fires forty times an hour is not a control; it is a training exercise in clicking yes.
Read the diff, always
Whatever the confinement, the last step never changes: the diff is read by a human before it goes anywhere.
The sandbox stops a mistake from destroying anything. It does nothing about a plausible, wrong change landing in your repository, which is the failure this whole course is about, and the only defence is the reading.
One practical note. The tools, their names, their permission models and their sandboxing stories change every few months, and anything written about specific products here would be wrong by next year. The three questions do not change: what can it read, what can it run, and who sees the diff before it lands.
Every lesson here is open. Your progress is recorded once you pass the AI at Work exam.
Check your understanding
A team runs agents inside containers with no credentials mounted, but auto-approves every command so work is not interrupted. What risk does the sandbox not address?
Pick the one you would defend. Your answer stays private.
Stuck on something?Ask Larissa, your AI tutor