How to Give an AI Coding Agent Safe Terminal Access

A confirm dialog with a shell command on it is not a great place to make security decisions on the fly. Here is a concrete tiering system, plus the setup steps and sandboxing options, for giving an AI coding agent terminal access without gambling on your machine.

Steve Jefferson
Steve Jefferson
Developer Advocate
8 August 20261 min read

Your AI coding agent just finished reading a failing test and proposed a fix. Now it wants to run a shell command to verify it, something like npm install && npm test. A confirm dialog is sitting on your screen. This is the moment most people either rubber-stamp everything forever, or panic and never let the agent near a shell again. Neither is right. Give an AI coding agent access to your terminal deliberately, with tiers for what it can run unattended, what needs a second look, and what it should never touch, and you get real speed without much of the downside.

This post lays out that tiering system, plus the setup steps and sandboxing options that make it hold up in practice.

What "terminal access" actually means here

When people talk about AI coding agent terminal access, they mean the agent can execute shell commands directly, rather than just suggesting code for you to copy and paste. That includes package managers, test runners, git, build scripts, and anything else you'd normally type yourself. It's one of several capability decisions that come up once you move past basic autocomplete into full AI coding agents that can act on your behalf.

This is different from file editing permissions. An agent that can only read and write files inside your project directory is contained by the filesystem. An agent that can run arbitrary shell commands can, in principle, do anything your user account can do: install software, change git history, hit the network, read your SSH keys, delete things that don't have an undo button. That gap is why terminal access gets its own conversation instead of being lumped in with "can it edit my code."

Most agent CLIs, including Claude Code and OpenAI's Codex CLI, separate two settings that people often conflate: the approval policy (when the agent has to ask you first) and the sandbox (what it's technically capable of reaching even if it doesn't ask). Claude Code's sandboxing documentation frames it plainly: isolation restricts what a command can access once it runs, while permission modes decide whether it runs at all. You want both, not one or the other.

Is it safe to let an AI agent run terminal commands?

Mostly, with caveats. The risk isn't that the model is malicious. It's that the model does exactly what it's told, including when the instructions are wrong, ambiguous, or planted by something other than you.

That third case is prompt injection: text sitting in a file, a GitHub issue, a package README, or an API response that the agent reads and treats as an instruction. If your agent has both terminal access and the ability to read untrusted content (a scraped web page, a dependency's changelog, a support ticket), a bad actor doesn't need to compromise your machine directly. They just need to get a sentence in front of the agent that looks like an instruction. Our post on what prompt injection actually is goes into how this plays out in more detail.

OWASP's Gen AI Security Project tracks this under a risk category it calls excessive agency: a system doing damaging things because it was granted more capability or autonomy than the task needed. Its LLM Top 10 guidance recommends limiting what agents can do by default and requiring a human in the loop for anything sensitive or hard to reverse. That's the whole argument for tiering terminal access instead of a single on/off switch: least privilege, applied to a shell.

The other failure mode is more mundane. The agent misreads a file path, runs a destructive command against the wrong directory, or "helpfully" cleans up something you needed. No malice, no injected prompt, just a model being confidently wrong with a tool that doesn't ask "are you sure" twice.

A three-tier system for terminal permissions

Blanket rules ("always confirm" or "never confirm") both fail in practice. Always-confirm trains you to click approve without reading, which defeats the point. Never-confirm is fine until it isn't. A tiered system, where the tier is based on what a command can actually do to your system, holds up better.

Here's the breakdown I use, and recommend adjusting to your own project rather than copying verbatim.

Tier

Examples

Why

Usually safe to auto-approve

npm test, pytest, git status, git diff, git log, linters, formatters, read-only build steps

Scoped to the project, don't touch the network or leave the working directory, easy to verify after the fact

Always require confirmation

git push, git commit, npm install of a new package, database migrations, docker commands, anything writing outside the project directory, deploy scripts

Reversible in theory but costly or embarrassing to get wrong, or they reach outside the sandbox (network, registries, remote servers)

Never allow (deny outright)

rm -rf outside the project, curl | bash or wget | sh, changes to ~/.ssh, ~/.aws, or shell profile files, sudo anything, force-pushing to a shared branch, commands that read and exfiltrate secrets

Irreversible, touches credentials, or grants persistence beyond the current session

A few notes on where the lines sit. Test and lint commands are auto-approve because their blast radius is the project directory and their output is easy to sanity-check. git push moves to confirm-required not because it's dangerous in isolation, but because it's the point where a mistake stops being local. The never-allow tier is short on purpose: it's for commands where "undo" isn't realistic, not everything that makes you nervous.

If you're deciding between letting an agent work in a terminal at all versus a more constrained IDE-integrated flow, see our comparison of running an AI agent in the terminal versus inside an IDE for the tradeoffs.

How to set up safe terminal access

  1. Start read-only. Run the agent in a mode where it can inspect files and propose commands but not execute anything without approval. Both Claude Code and Codex CLI support this as a baseline (Codex calls it read-only mode).

  2. Build your allowlist from real usage, not guesswork. Let the agent ask for approval for a day or two of normal work. Whatever it asks for repeatedly and harmlessly (test runners, linters, git diff) becomes your auto-approve tier.

  3. Write the deny list before the allow list matters. Explicitly block the commands in the "never allow" tier at the tool level, not just by convention. Claude Code's permissions.deny rules and Codex's sandbox boundaries both support this; deny rules should take precedence over anything the model or an approval prompt would otherwise let through.

  4. Put the agent in a sandbox, not just behind a prompt. A confirmation dialog stops a well-behaved agent. It does nothing once you've turned on an auto-approve or "skip permissions" mode. For anything unattended, run the session inside an OS-level sandbox, a dev container, or a VM.

  5. Keep secrets out of the agent's reach entirely, where you can. Don't rely on the agent "knowing" not to read your .env file. Use separate credentials for the sandboxed environment, or mount secrets read-only.

  6. Review what actually ran, after the fact. Most agent CLIs log the commands they executed. Skim that log periodically, especially after unattended runs, the same way you'd review a new teammate's first pull requests.

  7. Revisit the tiers as the project changes. A command that's safe in a side project (a destructive database reset, say) might belong in the never-allow tier once that project has real users.

If you're also worried about the agent editing files it shouldn't, the setup overlaps a lot with keeping an agent from changing code you didn't ask it to touch: both come down to scoping what the agent can reach before it starts working, not correcting it after.

Sandboxing: the backstop when the rules fail

Permission rules assume the agent asks before doing something risky. Sandboxing assumes it won't, and limits the damage anyway. Both matter, but they're not the same layer.

Claude Code ships a built-in sandboxed Bash tool that uses OS-level isolation (Seatbelt on macOS, Bubblewrap on Linux) to restrict filesystem and network access per command, plus a broader sandbox runtime that isolates the whole session, not just the shell. Codex CLI's sandbox documentation describes an equivalent split: a sandbox mode (read-only, workspace-write, or danger-full-access) that sets the technical boundary, separate from the approval policy that decides when it asks first. In both tools, pairing a permissive approval setting with a tight sandbox is a deliberate, documented combination, not a workaround.

For anything you'd call "unattended," a container or VM is worth the setup cost. A dev container with a default-deny network policy means that even if a command gets approved (or auto-approved) that shouldn't have been, it can't reach your production database or exfiltrate anything over the network. This is also the point where sandboxing AI coding agents overlaps with the broader question of whether it's safe to give an AI system access to your data at all, since a terminal is one of the more direct paths to that data.

None of this makes an agent's shell access risk-free. It makes the failure modes boring instead of catastrophic, which is the actual goal.

Once terminal access feels routine and the tiers hold up under real use, the next step up: staging environment access covers what changes once the agent can reach a shared environment instead of just your local machine.

Frequently asked questions

Is it safe to let an AI coding agent run terminal commands?

It's reasonably safe when the agent runs inside a sandbox and works from a tiered permission list, and considerably riskier when you grant blanket "always allow" access on your main machine with production credentials sitting in environment variables. The risk isn't that the model wants to cause harm, it's that it will follow bad or manipulated instructions exactly as written.

What terminal commands should I never let an AI agent run?

Anything irreversible or credential-adjacent: rm -rf outside the project directory, piping a downloaded script straight into a shell (curl | bash), edits to SSH keys or cloud credential files, sudo commands, and force-pushes to shared branches. If a mistake there can't be undone by reverting a commit, it belongs on the deny list.

Can an AI coding agent damage my computer?

Yes, in the same way a script you didn't fully read can: by running a destructive command, misinterpreting a file path, or following an instruction it shouldn't trust. The damage is rarely because the agent is trying to cause harm, it's because nothing stopped a plausible-sounding but wrong command from executing with your full user permissions.

Do I need Docker to sandbox an AI coding agent?

No, but it's the most common path. Lighter options exist, like Claude Code's built-in OS-level Bash sandbox on macOS and Linux, which doesn't require Docker at all. Docker-based dev containers or a dedicated VM give stronger isolation and are worth the setup cost once you're letting an agent run unattended or work on code you don't fully trust.

How did this land?

About the author

Steve Jefferson
Steve Jefferson

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.

Share

Get the next post in your inbox

One email a month. Product updates, engineering posts, and the best of Built with Swarmz.

I agree to receive emails about AI building tips and Swarmz product news. Unsubscribe any time.