# Claude Code Keeps Asking for Permission - the Allowlist Settings That Fix It

Every Bash call, every file write, every test run - approved, approved, approved. The permission prompts exist because the defaults trust nothing. The fix is not approving faster; it is telling the tool which commands never need to ask. That lives in the `permissions` block of `settings.json`.

## Where the settings live

Three files, checked in order, later ones win:

*   `~/.claude/settings.json` - your global defaults, every project
    
*   `.claude/settings.json` - project settings, commit this one so the team shares it
    
*   `.claude/settings.local.json` - project settings for just you, gitignore it
    

Put shared allowlists in the committed project file. Put your personal preferences (your editor, your scratch scripts) in the local one.

## The allowlist syntax

Permissions are pattern rules in three lists: `allow`, `deny`, and `ask`. A rule names the tool and the argument pattern:

```json
{
  "permissions": {
    "allow": [
      "Bash(npm run test:*)",
      "Bash(npm run lint)",
      "Bash(git status)",
      "Bash(git diff:*)",
      "Bash(git log:*)",
      "Read(*)",
      "Edit(src/**)"
    ],
    "ask": [
      "Bash(git push:*)"
    ],
    "deny": [
      "Bash(rm -rf:*)",
      "Read(./.env*)"
    ]
  }
}
```

Order of evaluation: `deny` beats everything, then `ask`, then `allow`. A command matching nothing falls back to the default - which is the prompt you are trying to escape. `:*` means any arguments; a bare pattern means exactly that command.

## What belongs on the allowlist

Read-only and reversible commands. A good test: could a new hire run this on day one without breaking anything? Test runners, linters, type checks, git inspection commands, build commands. Those are the prompts that interrupt you fifty times a day, and they are the safe ones.

File edits scoped to source directories (`Edit(src/**)`) are usually fine too - the changes are visible in `git diff` before you commit them. That is the review step that makes the permission unnecessary.

## What never goes on the allowlist

*   `git push` **and anything that publishes.** Keep it on `ask`. Publishing is the one step where a mistake leaves the building.
    
*   **Destructive filesystem commands.** `rm -rf` belongs on `deny`, not `allow`. An agent that can delete freely will eventually delete the wrong thing confidently.
    
*   **Secrets files.** Deny `Read` on `.env`, credential stores, and key material. Context that includes your secrets can end up in a prompt log or a generated file.
    
*   **Anything piped from the network.** `curl ... | bash` should require a human every time.
    

## The trap: allowlisting everything

The frustrated response to prompt fatigue is `"allow": ["Bash(*)"]`. That converts the tool from supervised to unsupervised. The prompts are annoying precisely because they catch the moments that matter - the unexpected `DROP TABLE` inside a migration helper, the force-push hidden in a "fix the branch" request. Allowlist the boring 90% so you actually read the prompts on the dangerous 10%.

## Team-level settings

Commit `.claude/settings.json` with the repo and new contributors inherit a sane baseline: tests and linters pre-approved, pushes and deletes gated, secrets unreadable. It is the same philosophy as a committed `.editorconfig` - one less thing every person configures alone. Review changes to it in pull requests like you would CI config, because it controls what automation can do unsupervised.

## The short version

Prompt fatigue comes from a default that trusts nothing. Fix it with a `permissions` block: allowlist read-only and reversible commands, keep publishing and deletion behind `ask`, deny secrets outright, and commit the project file so the team shares one baseline.

* * *

*Want the settings file pre-built? The* [*Agentic Coding Kit*](https://kitforgedev.itch.io/agentic-coding-kit) *ships a tuned* `settings.json` *permissions baseline, CLAUDE.md templates, and hook configs - 34 files, $19 one-time. Or start free with the* [*CLAUDE.md generator*](https://kitforgehq.surge.sh/generator/)*.*
