Stop Claude Code asking permission for every command, safely
On this page
  1. How Claude Code permission rules work
  2. Where the rules live
  3. A starter list for a typical web project
  4. What not to allow
  5. Other ways to get fewer prompts
  6. A checklist
  7. Where Joxo fits
  8. Frequently asked questions
  9. How do I stop Claude Code asking for permission every time?
  10. Where does "don't ask again" save the rule?
  11. Why are my allow rules ignored?
  12. Try it with your team

Blog / claude code

Stop Claude Code asking permission for every command, safely

Allow the commands you approve ten times a day, make risky ones always ask, deny secrets, and keep the list in one shared file. A starter list included.

Write down the commands you approve all day, such as tests, lint, git status and git diff, as allow rules in .claude/settings.json. Put commands that change shared things, such as pushes and installs, under ask. Deny reading secret files. Leave everything else prompting. That removes most prompts without giving the agent a blank cheque, and the whole team gets the same list.

Permission prompts are there for a reason, but forty a day for npm test teach you to press Yes without reading. Then the one prompt that mattered goes past unread. The fix is fewer prompts, each worth reading.

How Claude Code permission rules work#

Claude Code reads three lists from its settings files:

ListWhat it does
allowRuns the tool without asking
askAlways asks, even if an allow rule also matches
denyRefuses the tool

The Claude Code docs state the order: deny first, then ask, then allow. The first list that matches decides, and a narrow allow can't carve an exception out of a broad deny. So you can allow Bash(git *) broadly and still make Bash(git push *) ask.

A Bash rule matches the command as written, and * stands for anything:

RuleMatchesDoesn't match
Bash(npm run build)npm run buildnpm run build --watch
Bash(npm run *)npm run build, npm run test --watchnpm install
Bash(git log *)git log --oneline -5git push

Put the * after the subcommand. Bash(git log *) allows only git log; Bash(git *) allows every git command, including the ones you didn't mean.

Where the rules live#

FileWho it applies toIn git?
.claude/settings.json in the projectEveryone on the projectYes, commit it
.claude/settings.local.json in the projectYou, in this projectNo
~/.claude/settings.jsonYou, in every projectNo

When you pick "Yes, and don't ask again" on a prompt, Claude Code saves that rule to .claude/settings.local.json. That is why one person's agent stops asking and a teammate's doesn't: the rule is in a personal file. Rules the whole team agrees on belong in the shared .claude/settings.json.

One thing caught us while testing this post: allow rules in a project's shared settings are ignored until that folder has been trusted. Run Claude Code interactively in the folder once and accept the trust prompt. Deny rules work from the start.

A starter list for a typical web project#

Adjust the commands to your project's tools. This one uses pnpm:

json
{
  "permissions": {
    "allow": [
      "Bash(pnpm test *)",
      "Bash(pnpm run lint *)",
      "Bash(git status *)",
      "Bash(git diff *)",
      "Bash(git log *)",
      "Bash(git commit *)"
    ],
    "ask": [
      "Bash(git push *)",
      "Bash(pnpm add *)"
    ],
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Bash(git push --force *)",
      "Bash(rm -rf *)"
    ]
  }
}

Why each group:

  • Allow holds things that only read, or only touch your own branch, and that you approve many times a day. Tests and lint are the big ones.
  • Ask holds things that reach other people or add code you didn't write: a push, a new package. You want to read the exact name each time.
  • Deny holds things you never want to approve by reflex: reading secrets, force-pushing, deleting folders.

If your settings file already has other keys, add permissions next to them. Type /permissions in Claude Code to see every rule and which file it came from; you can add and remove rules there too.

What not to allow#

A few rules feel convenient and quietly remove the safety check:

RuleWhy not
Bash(*) or BashEvery shell command, including deletes and deploys
Bash(git *)Includes push, reset and force-push
Bash(npm *)Includes installing any package from the internet
Bash(curl *)Anything can be downloaded or sent anywhere
Bash(ssh *)Commands on other machines

Also, don't treat deny as a wall. A deny rule matches the usual way a command is written. The docs give the example of git -C . push, which a Bash(git push *) rule doesn't match. Deny catches the common case; for real limits, run the agent where it can't reach what it shouldn't, and keep secrets out of the project folder.

Other ways to get fewer prompts#

Accept edits mode. Press Shift+Tab until Claude Code shows accept edits mode: file edits and simple file commands such as mkdir and mv inside the project run without asking, while other shell commands still ask. It suits a session where you are watching the diff anyway.

Ask once, for the right scope. When a prompt offers to save a rule, check what it would cover before choosing it. A rule for one command in one project is fine. A rule for a whole tool is not.

Answer from where you are. Some prompts must wait for you: that is the point. If you are away from the keyboard, a phone that shows the full command and lets you answer saves the wait. Our post on approving prompts from your phone covers what to allow there and what to keep for the keyboard.

A checklist#

  1. List the prompts you approve most this week. Each one that only reads or tests becomes an allow rule.
  2. Pushes and installs go under ask.
  3. Secret files and force-pushes go under deny.
  4. The list lives in .claude/settings.json, committed, so every teammate's agent follows the same rules.
  5. Personal rules stay in .claude/settings.local.json.
  6. Check /permissions once a month and remove what you no longer need.

Where Joxo fits#

When several people each run their own agent on one project, Joxo keeps them on one task board with shared decisions, so the rules you agree on are the same for everyone. Prompts that do need a person can reach the phone of the person whose computer it is, with the whole command shown, and nothing is approved if nobody answers. Setup is on the setup page.

Frequently asked questions#

How do I stop Claude Code asking for permission every time?#

Add allow rules for the commands you approve often, such as Bash(npm test *), to .claude/settings.json in your project, or use /permissions. Keep pushes and installs under ask and deny reading secret files, rather than allowing everything.

Where does "don't ask again" save the rule?#

In .claude/settings.local.json at the root of the repository. It applies only to you. Move rules the whole team wants into the shared .claude/settings.json.

Why are my allow rules ignored?#

The most common reason is that the project folder hasn't been trusted yet: run Claude Code interactively there once and accept the prompt. Also check that no ask or deny rule matches the same command, since those win over allow.

See also: Set up Claude Code for a team, for which settings to share and which to keep personal.