Skip to content

Field note

Claude Code Permission Prompts: Safe Settings

Constant permission prompts are Claude Code telling you that the allowlist does not match the work, and the fix is a short, specific set of rules rather than a blanket bypass.

Constant permission prompts are Claude Code telling you that the allowlist does not match the work, and the fix is a short, specific set of rules rather than a blanket bypass.

What the prompts are doing

Claude Code uses a tiered system. Reading files inside the working directory needs no approval. Shell commands ask, apart from a built-in set of read-only commands. File edits ask, and a "don't ask again" answer lasts until the session ends. Web fetches ask except for a set of pre-approved documentation domains.

Two facts shape everything else. First, these rules are enforced by Claude Code itself, not by the model, so an instruction in CLAUDE.md cannot grant or remove access. Second, rules are evaluated deny first, then ask, then allow, and the first match wins. A broad deny beats a narrow allow at any level, including project settings against user settings.

The modes and when each is safe

default (Manual)Prompts on first use of each toolDay one, unfamiliar repositories, anything touching production data
acceptEditsAuto-accepts file edits and simple file-system commands in the working directoryYou trust the edits and will review the diff before commit
planReads and explores but does not edit source filesScoping a task before letting the agent change anything
autoA classifier reviews actions against your request instead of promptingAvailable to some accounts; try it on a low-risk repository first
dontAskDenies anything that would prompt instead of askingUnattended runs where you have already allowlisted every needed tool
bypassPermissionsSkips prompts, including writes to protected paths such as .gitOnly inside a container or VM with nothing on it you cannot lose

Switch modes with Shift+Tab during a session, or set defaultMode in a settings file. Start in plan mode for a new task, move to Manual to make the change, and reserve acceptEdits for repositories where the review gate is already in place.

Build the allowlist from observed commands

  1. Work in Manual mode for a week and note which prompts repeat. They will be the same handful: the test runner, the linter, git status, git commit.
  2. Open /permissions. It lists every rule and the settings file each one came from, and changes apply from the next tool call.
  3. Write rules for the exact commands you saw, with * after the subcommand. Bash(npm run *) allows every npm script; Bash(git commit *) allows commits but not pushes. A rule with no * matches one exact command.
  4. Add deny rules for the paths and actions the agent should never touch: Read(./.env), Read(./secrets/**), Bash(git push *). A Read deny also blocks edits and creation on that path.
  5. Put team rules in .claude/settings.json and commit it. Personal overrides go in .claude/settings.local.json, which stays out of git. Allow rules in the committed file apply only after each person accepts the workspace trust dialog for that folder.

A starting file for a Node project looks like this:

{
  "permissions": {
    "allow": ["Bash(npm run *)", "Bash(npm test *)", "Bash(git status)", "Bash(git diff *)", "Bash(git commit *)"],
    "deny": ["Bash(git push *)", "Read(./.env)", "Read(./.env.*)", "Read(./secrets/**)"]
  }
}

Expect to add a few rules in the first fortnight and then stop. If the list keeps growing, the agent is doing work the team has not agreed it should do.

What the admin should lock

For a business with several developers, some settings belong in managed settings that no user or project file can override:

  • permissions.disableBypassPermissionsMode set to "disable" so nobody can switch off prompts on a laptop that holds customer data. permissions.disableAutoMode does the same for the classifier mode.
  • allowManagedPermissionRulesOnly where the organisation, not the repository, must own the permission rules.
  • A deny list for reading credential files and for network commands that should not run from an agent session.
  • Sandboxing where the platform supports it, which enforces file-system and network boundaries independently of the command text.

Managed settings have the highest precedence; a managed deny cannot be overridden by a flag or a project file. Deploy them through device management, then run /status on a developer machine to confirm the source shows as managed.

Signs the settings are wrong

  • The same command still prompts. Usually the * is in the wrong place. Claude Code matches everything before the first * literally, so Bash(git * main) does not do what people expect.
  • An allow rule is ignored. A deny or ask rule at another level matches first. /permissions shows which file it came from.
  • A push written differently gets through. Bash rules match the command as written, so git -C . push is not git push *. Use a PreToolUse hook for controls that must not depend on spelling.
  • Prompts vanish entirely. Someone started the session in bypass mode. Check which mode the session began in and whether managed settings should forbid it.

Permission rules answer "may the agent do this?"; they do not answer "should a person approve this?". The approval versus permission note draws that line, and our Claude Code workshop sets both up on your repository.

Source basis

Keep reading

Related notes

26 Aug 2026 · 5 min

Claude Code Hooks: Put Checks Before the Merge

A review gate built from Claude Code hooks runs the same cheap checks on every agent action, so the human reviewer only sees diffs that have already passed the boring tests.