How to Limit What a CLI Agent Can Touch
Good cli agent permissions limit blast radius, not express distrust. Here's how to constrain read scope, write scope, and command scope with deny rules that beat allow rules — so a mistake stays small.
# The three axes: read scope, write scope, command scope claude --allowedTools "Read" "Edit" "Bash(pnpm test)"
Picture this: you've brought on a contractor for a two-week engagement, and you want to give them a terminal agent to move fast on a well-defined feature. But this is a production codebase with customer data, payment code, and infrastructure config sitting right next to the feature they're building. You wouldn't hand a new contractor unrestricted production access on day one, and the same logic applies to the agent they'll be driving. The question isn't whether the agent is trustworthy — it's how to bound what it can touch so a mistake stays small. That's what cli agent permissions are for: limiting blast radius, not expressing distrust.
Get this right and the agent is a productive teammate with a safe workspace. Get it wrong and a single confused instruction reaches code it never should have.
What Are CLI Agent Permissions?
Permissions are the rules that decide what an agent may read, edit, and execute — and, just as importantly, what it may not. They exist because an agent optimizing to complete a task will use whatever access it has, and "complete the task" is not the same goal as "stay inside safe boundaries." Permissions make the boundaries explicit so the agent's drive to finish can't quietly carry it somewhere expensive.
Every serious terminal agent exposes three layers of control: what files it can see, what files it can change, and what commands it can run. Good setups constrain all three, because a gap in any one is a gap in the whole.
[object Object],
claude --allowedTools ,[object Object], ,[object Object], ,[object Object],What this does: Grants reading, editing, and exactly one command — the test runner — while everything outside that set stops for approval. Each of the three axes is constrained explicitly rather than left open, which is the baseline of a safe setup.
Why It Matters
The stakes are that an over-permissioned agent turns a small mistake into a large one. Ask an agent to "update the config" with repo-wide write access, and a misread instruction can rewrite the wrong config in the wrong service. The same mistake, made by an agent scoped to a single directory, is contained to that directory. The mistake rate might be identical; the consequence is what permissions control.
There's a subtler reason too. Broad access means the agent reads code — and secrets, and unrelated services — that dilute its focus and inflate its token cost. Tight cli agent permissions don't just make the agent safer; they make it sharper, because it's working within exactly the context the task needs and nothing more.
⚡ Pro tip: Start every agent engagement read-only and let it earn write access. Open in a plan or ask mode, watch how it proposes to approach the task, and only grant edit access once you've seen it reason sensibly. Most permission disasters happen because write access was granted before anyone understood what the agent intended to do.
How CLI Agent Permissions Actually Work
Permissions resolve as a layered system, and understanding the layers is what lets you set them well.
The foundation is the allow/deny model, and the critical rule is that deny beats allow. You can grant a broad category and still carve out hard exceptions, and the exceptions win.
[object Object],
,[object Object],[object Object], ,[object Object],
,[object Object],[object Object], ,[object Object],[object Object],[object Object], ,[object Object],[object Object], ,[object Object],[object Object],[object Object],
,[object Object],[object Object], ,[object Object],[object Object],[object Object], ,[object Object],[object Object], ,[object Object],[object Object],
,[object Object],
,[object Object],What this does: Lets the agent edit anything under the feature directory and run tests, while absolutely refusing to touch payment code, environment files, or push to a remote — even though those paths sit inside the broader repo. Deny rules take precedence, so they're your hard floor regardless of how a task is phrased.
On top of that sits the permission mode, which is a spectrum from cautious to permissive: a plan mode that only proposes, an ask-first mode, an accept-edits mode that auto-applies file changes but still gates commands, and a bypass mode that gates nothing. The mode sets the default posture; the allow/deny rules set the specific boundaries.
[object Object],
claude --permission-mode plan ,[object Object],
claude --permission-mode acceptEdits ,[object Object],What this does: Shows the two ends of the everyday range — plan mode for reviewing intent before anything happens, accept-edits for flow once you trust the task. Matching the mode to your confidence in the task is how you tune throughput against caution.
The third layer is scope by path. Launching the agent from a subdirectory, using a sparse checkout, or scoping edit rules to specific directories all narrow what "the repo" even means to the agent. For the contractor scenario, scoping edit access to the feature directory means the payment code isn't just deny-listed — it's out of the agent's working world entirely.
⚡ Pro tip: Put your deny rules in a committed settings file, not in each person's local setup or in the prompt. A denylist that lives in the repo protects everyone who runs an agent against it, can't be forgotten in an individual's config, and survives the contractor's engagement ending. Boundaries belong in version control, not in memory.
Setting Permissions for Real Situations
The contractor scenario, done right: edit access scoped to the feature directory, payment and infra paths on the committed denylist, an allowlist covering only the dev-loop commands, and no push access — the contractor's agent opens PRs a full-time engineer reviews.
A regulated team handling customer data: deny the agent read access to directories holding sensitive fixtures or config, run against a local model on the most sensitive repos so nothing leaves the network, and enforce the whole policy through an org-managed settings layer no individual can relax.
A solo developer on a side project: you can run looser, but still deny force-pushes and destructive deletes, and still commit before letting the agent write, so a mistake is a git reset away rather than a lost afternoon.
⚠️ Common mistake: Reaching for bypass mode to escape approval fatigue. Turning permissions off entirely trades a small, constant friction for an unbounded, occasional catastrophe. The right fix for too many prompts isn't zero prompts — it's a good allowlist that pre-approves the routine command patterns so only genuinely novel actions stop for a look.
Auditing What the Agent Actually Did
Permissions are a preventive control — they stop the agent from doing certain things. There's a second kind of control worth pairing with them: detective controls that record what the agent did do, so you can review it after. Prevention keeps the agent inside the lines; auditing tells you where it went inside them. Serious setups use both, because no permission scheme is perfect and the audit trail is how you catch what the boundaries missed.
The simplest version is capturing every session's actions to a log you can review. Many agents can emit their tool calls and commands as structured output, which you append to a durable record.
[object Object],
claude -p ,[object Object], --output-format json | ,[object Object], -a agent-audit.jsonl | jq ,[object Object],What this does: Runs the task while appending a structured record of the session to an audit log. Later, that log tells you exactly what the agent touched and ran, so a surprising outcome becomes something you can trace rather than guess at. The permissions bounded the agent; the log shows you what it did within those bounds.
The audit trail matters most for the operations you did permit. You allowed the agent to edit the feature directory and run tests — the log shows you which files it actually changed and which commands it actually ran, which is where a subtle problem hides. A boundary tells you what couldn't happen; the record tells you what did.
⚡ Pro tip: Pair a tight permission set with a durable audit log from day one. Together they answer both questions that matter after an incident — "how did this happen" and "what else did the same session touch" — and the log costs almost nothing to keep. Prevention plus detection beats either alone.
⚡ Pro tip: Review the audit log periodically even when nothing went wrong. The patterns in what the agent routinely does often reveal permissions that are looser than they need to be — a command it's allowed but never uses, a directory it can write but shouldn't. The log is how you tighten permissions based on real behavior instead of guesswork.
Common Mistakes
⚠️ Common mistake: Granting write access to the whole repo when the task lives in one corner of it. The blast radius of every future mistake is now the entire codebase, for no benefit — the agent didn't need the rest to do the task. Scope edit access to where the work actually is, and the worst case shrinks to match.
The second mistake is treating permissions as a one-time setup. The right boundaries for a read-only exploration differ from those for an autonomous overnight job, which differ again from an interactive feature session. Permissions are a dial you set per task, not a switch you flip once and forget.
Conclusion
Sound cli agent permissions come from constraining all three axes — read scope, write scope, command scope — with deny rules that beat allow rules, a mode matched to your confidence, and path scoping that shrinks the agent's world to the task. It's not about distrusting the agent; it's about making sure that when a mistake happens — and one eventually will — it's small, contained, and cheap to undo.
The allow/deny rule sets, the per-task mode choices, the committed denylists — these are the same guardrails across every repo and every engagement. Save them in PromptABCD so your next agent starts inside a safe boundary you've already thought through, instead of one you improvise while a contractor waits.
Continue Reading
Save the prompts from this post
PromptABCD is a free prompt manager. Paste, organize, and reuse your best AI prompts — no more hunting through chat history.
