9.4 Permission Policy¶
The last conversion. Since Chapter 3 you've been reading permission gates one at a time. As connections and tools grow, repeated prompts can produce gate fatigue. Permission policy records your judgment about what's routine, what's sharp, and what's forbidden in configuration, preserving attention for decisions that still require it.
What you will learn
- Structure policy in three bands: allow, ask, deny.
- Configure allowlists and deny rules in Claude Code settings.
- Choose permission modes deliberately — including what "auto-accept" actually trades.
Builder principle
Attention is the scarcest thing in your system. Spend none of it on ls, all of it on deploy. Policy is how.
The three bands¶
Every action your agent might take falls into one of three bands — and you've been sorting them by hand for eight chapters:
ALLOW — the bounded and understood. File reads, ls, git status, or a reviewed harness may be candidates after you know their arguments, data reach, hooks, and child processes. "Read-only" does not automatically mean confidential or cheap.
ASK — the sharp. Actions worth a real three-part read every time: installs, network-touching commands, writes through MCP servers, anything outside the project. The band where gates work — because policy just emptied the noise out of them.
DENY — the forbidden. Your 8.5 no-undo list and 9.2 guard targets, promoted to configuration: force-push, recursive deletes outside temp paths, edits to protected assets, or use of production credentials. Deny rules reduce what the agent may request; OS, service, and credential boundaries enforce what the underlying process can actually reach.
Writing it down¶
Policy lives in the same settings files as your hooks (.claude/settings.json project-level, user-level for personal invariants — the layering is instinct by now). Claude Code supports allow/deny rules over tools and commands, with pattern matching for command shapes. The meta-move builds it, same as 9.2:
Set up permission rules in .claude/settings.json from this policy:
ALLOW: git status/diff/log/add/commit, ls, cat, our scripts/check.sh,
npm test.
DENY: git push --force, rm -rf anywhere outside /tmp, any edit to
.env or assets/logo.svg.
Everything else keeps asking. Check current settings docs for exact
syntax, and explain each rule back to me before writing it.
(Explain-back rule in full effect — permission config is the most trust-sensitive file in the repo. And note what stays out of ALLOW: git push plain. Publishing is a seam you keep, at least until your harness has months of receipts.)
Bash patterns are not a shell policy language
Bash(...) rules match command patterns, and * may span multiple arguments. Spacing, compound commands, wrappers such as npx or environment runners, and commands such as find -exec change what a broad rule permits. Prefer exact or narrow rules, inspect the current permission syntax, and test both expected matches and bypass-shaped non-matches. Do not use a broad prefix as the only boundary around destructive or sensitive access.
Add the OS boundary¶
Run /sandbox to inspect or enable Claude Code's Bash sandbox where the platform supports it. Sandboxing restricts Bash child processes at the operating-system level; permissions govern tool decisions and prompts. Use both:
- Permissions deny or ask before a tool is attempted.
- Sandboxing limits filesystem and network reach even if model judgment or a command pattern fails.
- Scoped credentials and service policy limit what an allowed process can do after it reaches a service.
The sandbox applies to Bash and its child processes, not every Claude Code tool. Native Windows does not currently support Bash sandboxing; WSL 2 does. Read/Edit, WebFetch, and MCP still need their own permission, path, domain, and server controls.
Two audits keep policy honest, both scheduled with your 8.5 quarterly:
- The fatigue audit: what did you rubber-stamp this week? → ALLOW candidates.
- The drift audit: what's in ALLOW that the project outgrew? Policy too permissive fails silent, so this one matters more.
Permission modes — the dial, not the switch¶
Beyond rules, Claude Code has session-level modes (the ++shift+tab++ cycle you've touched since 4.2): normal gating, plan mode (read-only — the most restrictive), and auto-accept modes where edits proceed without per-action prompts.
Auto-accept is neither reckless nor forbidden — it's a trade you price: you're trading per-action review for after-the-fact review. The price is fair exactly when the rest of this chapter is in place:
Auto-accept is earned when:
├── deny rules fence the catastrophic (9.4)
├── hooks + harness catch defects in-loop (9.2, 9.3)
├── Git checkpoints tracked file state (3.3, within its boundary)
└── the task is well-briefed and scoped (2.3, 5.5)
With that stack, auto-accept may fit a low-risk, scoped task. Review still includes untracked files and external effects, not only the diff. The stack lowers risk; it is not a license to expose confidential data or irreversible systems.
Start conservative and let the fatigue audit drive: after a week, promote your five most-rubber-stamped read-only actions to ALLOW, and put your no-undo list in DENY today. Try auto-accept first on something with zero stakes and a good harness — your practice site, a scoped task, twenty minutes. Feel the speed, review the diff after, and price the trade yourself. Deliberate is the goal; timid isn't.
The committed settings file is now carrying policy + hooks + (via scripts) harness wiring — treat changes to it like changes to CI config: reviewed, owned, deliberate. Team policy questions worth settling once, in the file, not per-engineer: the shared DENY floor (no force-push to main, no prod credentials in agent reach), the ALLOW set for your build/test tooling, and which paths are hook-guarded. This is also your Chapter 10 pre-work: parallel agents inherit this policy, and orchestration without a policy floor is just concurrency with vibes.
Try it now¶
The chapter's capstone — assemble the full machine:
- Write your three bands on paper first: sweep the week's rubber stamps into ALLOW, your 8.5 no-undo list into DENY.
- Install via the meta-move, explain-back enforced. Verify mechanically (attempt a denied action; watch it refuse — mechanism gets seen, per the house rule).
- Run the earned-license experiment: one well-scoped, well-harnessed task in auto-accept. Review the diff after. Price the trade in your journal.
- Step back and inventory the whole Chapter 9 machine now running: hooks at the seams, harness telling truth, policy spending your attention. Cross the last items off the 9.1 conversion queue. That queue is the chapter, completed.
Check your understanding¶
- Define the three bands and give two examples each from your own week.
- Why is rubber-stamping a policy signal, and which audit converts it?
- What exactly does auto-accept trade, and what four things make the price fair?
- Why does DENY beat "ask carefully" for the no-undo list?