Safe Agent Edits

The edit policy

The edit policy is a per-project rule set that decides, for every file a Claude Code session tries to write, whether the write is allowed, must be reviewed, or is denied outright.

Configure it in Project settings → Safe edits, and switch it on with Enable the policy. Each rule has a ? that explains it in place.

The part that matters

The policy is enforced inside the PreToolUse hook — before the tool call runs, and outside the model's reach. Which means:

A deny holds even when the session is running under acceptEdits or bypassPermissions.

The agent cannot argue with it or be prompted around it, because it is never asked. That is what lets you run an agent fast on a client's repository.

The lists below govern the agent's edit tools. A shell can run any program, so commands are covered separately, and on a best-effort basis — see Shell commands. For a hard boundary, run the project in a VM or a container.

The three lists

  • Blocked — hard deny. Edits to these paths are always refused.
  • Protected — force review. Edits to these always stop at the accept/deny diff, even under acceptEdits.
  • Auto-accepted paths — never ask. Edits to these go through without a prompt.

They are checked in that order, and the first match wins. An auto-accepted path can never override a block or a protection: an allowlist able to cancel a deny would make the deny a suggestion.

The Blocked list: .env files, keys and a secrets folder, each hard-denied.

The Protected list: migrations, auth, CI workflows, Dockerfile and Terraform, each forced through review.

How a pattern matches

A pattern with no slash is a name, matched at any depth. A pattern with a slash stays where you wrote it, relative to the project root — start it with */ or **/ to mean "anywhere". A bare name with no wildcard and no extension, such as node_modules, covers a folder of that name and everything in it. Matching ignores case.

Pattern Matches
*.css a .css file in any folder
.env.* .env.local, .env.production … anywhere, but not .env itself
node_modules a file or folder with that name, anywhere, and everything inside it
*/tests/* anything inside a tests folder, at any depth
dist/ everything under the dist folder at the project root
src/**/*.pem .pem files anywhere under the root's src folder
**/migrations/** everything under any migrations folder

A row that is only slashes is refused rather than quietly matching everything. When you save, duplicates collapse, and a rule that can never fire — because a stricter list already covers it — is reported, rather than sitting there looking as if it works.

Test the rules

Test the rules takes a path or a shell command and tells you what the saved policy would do with it. It answers by running the real hook with your saved policy — not a second copy of the matching logic — so what it tells you is what the agent will meet.

Testing the rules on .env.production: editing it is refused by the .env.* pattern.

The switches

  • Block edits outside the project root. The agent's own .claude and .codex folders are exempt: its notes, plans and memory are written without asking, and a change to its settings, hooks, skills or commands always asks.
  • Auto-approve edits that match no rule. A blanket fast path for in-project edits that no list mentions. It runs last, so it never overrides a block or a protection.
  • Don't let the shell edit files, and the switches that pre-approve commands — see Shell commands.
  • The read-side rules — see Read rules.

What to protect

Typical rules:

  • Blocked: .env*, credentials, CI secrets, anything under deploy/.
  • Protected: database migrations, authentication code, payment code.

Start restrictive. A denied edit costs you ten seconds; an unreviewed migration on a client database costs you a client.

Scope

Claude Code sessions. A Codex session is not covered — see What is supervised.

Last updated Oct 11, 2026