What Tool Access a Coding Agent Should Have
A coding agent with a shell, a file editor, and the ability to run tests is a different animal from one with those tools plus a browser, a database client, and a package manager pointed at production. The difference is not capability. It is blast radius. Every tool added to an agent's kit widens the set of irreversible actions it can take before a human notices something went wrong. The question of what tool access a coding agent should have is therefore not a feature checklist. It is a question about which mistakes should be cheap and which should be impossible.
The default posture in most agent frameworks is permissive. Give the model a terminal, a filesystem, network egress, and credentials, then hope the system prompt holds. That posture works in a sandbox and fails in a repository that matters. The interesting design work happens in the middle: granting enough access that the agent can actually finish a task, while keeping the consequences of a bad tool call inside a boundary a person can inspect and undo.
Reading the Codebase Is the Floor, Not the Ceiling
Every coding agent needs to read files, search for symbols, and inspect git history. Without that, it is guessing at the shape of the code. The access here should be broad and cheap: the whole repository, read-only, plus the ability to run language-server queries. Reading is the one category where more is almost always better, because a read cannot break anything and a narrow read scope produces worse edits.
The exception is secrets. A repository often contains a local env file, a credential cache, or a signed token sitting in a config directory. An agent that can read everything can also read those and paste them into a commit or a log line. The fix is unglamorous: exclude known secret paths from the read scope, and rotate anything that leaks anyway. Broad reads, narrow secrets.
Writing Files Wants a Working Copy, Not the Main Branch
An agent that edits code should edit a branch, a worktree, or a scratch copy, never the main checkout on a developer's machine. This sounds obvious and is routinely violated by setups that let the agent run sed against whatever directory the process inherited. The consequence is a half-finished refactor sitting uncommitted in someone's working tree at the end of the day, tangled with their own changes.
A dedicated worktree costs almost nothing to create and gives the agent a clean surface to make a mess on. The human reviews a diff instead of reconstructing what happened. When the work is bad, git worktree remove deletes the whole attempt in one command. That reversibility is worth more than any clever prompting.
Running Tests and Linters Belongs in the Loop
An agent that cannot execute the test suite is writing prose about code. It needs to run the tests, read the failures, and try again. This is the single highest-value execution permission in the whole kit, because it converts the agent from a text generator into something that can close a feedback loop on its own.
The permission should be scoped to the project's own test and lint commands, not to arbitrary shell. Running pytest or npm test is safe in a container. Running whatever string the model produces is not. The practical implementation is an allowlist of commands the agent may invoke, with the full shell left to a human. Most agent frameworks support this; most people leave it wide open because the allowlist takes an afternoon to write.
Network Access Is Where the Sandbox Ends
Package installation needs the network. So does fetching documentation, calling an API under test, and pulling a container image. Network egress is also the tool that turns a contained mistake into an incident: an agent that can reach the internet can exfiltrate a secret, hit a production endpoint, or install a package that was typosquatted last week.
The workable middle is a proxy with an allowlist of registries and documentation hosts, plus a hard block on anything that resolves to internal infrastructure. The agent gets to install dependencies and read docs. It does not get to curl an internal admin panel because a stack trace mentioned the hostname. That distinction has to be enforced at the network layer, because a system prompt asking the model to be careful is not a security control.
Database and Cloud Clients Need Read Replicas and Dry Runs
The moment an agent can query a database, two very different permissions get conflated. Reading schema and sample rows is enormously useful for writing correct migrations and queries. Writing to the database is a different category entirely, and the gap between the two is where most of the damage lives.
Give the agent a read replica or a snapshot, and give it a migration tool that defaults to a dry run and prints the planned statements. The human approves the apply. An agent that can run DROP TABLE against the primary because the connection string was in the environment is not a productivity tool; it is an uninsurable liability. The same logic applies to cloud CLIs: read-only credentials for inspection, and a separate, explicitly confirmed path for anything that creates, modifies, or destroys a resource.
The Commit and Push Boundary
Committing is cheap and reversible. Pushing to a shared branch is not. An agent should be able to stage and commit inside its worktree so its work is inspectable as a diff, and it should not be able to push to a protected branch without a human in the loop. Opening a pull request is a reasonable permission to grant, because a PR is a review surface rather than a deployment.
Force-pushing, rewriting history on shared branches, and merging without review belong in the category of things the agent cannot do at all. These are rare operations for a human and near-never correct for an agent acting autonomously. Removing them from the tool list is simpler and safer than trying to detect when the model is about to do something regrettable.
What Should Stay Out of Reach Entirely
Production credentials, deploy keys, and anything that can spend money belong off the list. So does the ability to disable the safety mechanisms themselves: turning off branch protection, editing CI config to skip tests, or modifying the agent's own permission file. An agent that can rewrite its own guardrails does not have guardrails.
Long-running background processes are another category worth excluding. A dev server that never exits holds ports, consumes memory, and confuses the next task. The agent should start a server, run a check against it, and shut it down, all within a bounded command. Anything that outlives the task is a leak the human has to clean up later.
Tool Access Should Follow the Task, Not the Agent
The most useful reframing is to stop thinking about what a coding agent is allowed to do in general and start thinking about what a specific task requires. Fixing a typo in a README needs read access and a commit. A dependency upgrade needs network, tests, and a lockfile. A migration needs a replica and a dry run. Granting the union of all of these to every task is how agents end up with production access to do a documentation change.
Task-scoped tool sets are more work to set up and dramatically easier to reason about. When something goes wrong, the audit question becomes tractable: what was this task permitted to touch, and did it stay inside that envelope? With a single permissive tool set, the answer is always the same unhelpful sentence: it could have touched anything.
The Permission Log Is the Real Deliverable
Whatever set of tools an agent gets, every invocation should be logged with the arguments, the working directory, and the outcome. Not for debugging the model. For reconstructing what happened after a bad afternoon. A team that cannot answer "what did the agent run at 3 p.m. on Tuesday" is not ready to give an agent write access to anything that matters.
The log also changes behavior at design time. Once the permission list is visible, the absurd entries stand out. A tool list that includes a production database client and a deploy command, granted to an agent whose job is writing unit tests, is a list nobody read before shipping. Making the list explicit is the cheapest audit a team will ever run, and it usually removes half the entries on the first pass.
The instinct to give an agent everything it might need is understandable and wrong. The better instinct is to give it exactly what the current task needs, put the rest behind a human, and log every call so the boundary stays visible. A coding agent with a worktree, a test runner, a read replica, and no production keys will finish most tasks and fail safely on the rest. That is the trade worth making.

