Claude Code keeps asking permission: allow rules that actually work

Claude Code asks before it runs most shell commands. You can pre-approve the safe, repetitive ones, such as your tests and linter, with allow rules. The catch is that the rules have precise matching behavior, and in one common setup they are silently ignored. We tested each case below in real Claude Code 2.1.278 sessions in September 2026.

The short version: write the command you want approved and put a * after the subcommand. A rule with no * matches that exact command and nothing else. And if you put allow rules in a project's .claude/settings.json, they only apply after you accept Claude Code's "trust this folder" dialog.

Where to put the rules

{
  "permissions": {
    "allow": [
      "Bash(npm test)",
      "Bash(npm run build *)"
    ]
  }
}

The trust trap: allow rules that silently do nothing

Claude Code's documentation says allow rules in a project's .claude/settings.json grant capability, so it applies them only after you accept the workspace trust dialog for that folder. deny rules are not affected, since they only restrict. The dialog appears in interactive sessions only. A claude -p run never shows it, so the project's allow rules are never used there, and Claude Code prints a "this workspace has not been trusted" warning instead.

We hit exactly this. With Bash(npm test) in the project's .claude/settings.json, every command we tried in a claude -p run was refused with "This command requires approval", including npm test itself. When we moved the same rules to .claude/settings.local.json, they worked. If your rules seem to do nothing, check where they live. If you share rules through git, each teammate must accept the trust dialog once.

How matching works (tested)

With the two rules above, Bash(npm test) and Bash(npm run build *), we asked Claude to run eight commands:

CommandResultWhy
npm testAllowedExact match
npm test -- --silentRefusedA rule without * matches only that exact command, so any extra argument breaks it
npm run buildAllowedA trailing * after a space also matches the bare command
npm run build -- --watchAllowedThe * stands for any arguments
npm run lintRefusedNot covered by any rule
timeout 30 npm testAllowedClaude Code strips wrappers such as timeout, time, nice and nohup before matching
NODE_ENV=production npm testAllowedKnown-safe variable assignments such as NODE_ENV are ignored
npm test && npm run lintRefusedEach part is checked separately, and npm run lint has no rule

The fourth row is worth a second look: the command was allowed, and then failed on its own, because we passed --watch to a script that could not take it. An allow rule decides permission only. It does not check that the command makes sense.

Where to put the star

The documentation is direct about this: put the * after the subcommand. Bash(git log *) allows only git log commands. Bash(git *) allows every git subcommand, including git push. The space before a trailing * matters too: Bash(ls *) matches ls -la but not lsof, whereas Bash(ls*) matches both.

A safe starting list

Approve the things you would run without thinking, and nothing that changes state outside your project:

{
  "permissions": {
    "allow": [
      "Bash(npm test *)",
      "Bash(npm run lint *)",
      "Bash(npm run typecheck *)",
      "Bash(npm run build *)"
    ]
  }
}

Claude Code already runs a built-in set of read-only commands without asking, such as ls, cat, echo, pwd, head, tail, grep, wc and diff, so you do not need rules for those. Use your own script names in place of the examples.

Allow rules that are riskier than they look

Allow rules are not a safety net

Allow rules remove prompts. They do not stop anything. For the commands you never want run, use deny rules, and note that even a deny rule can be sidestepped by a different spelling of the command. Both halves are covered in how to block git push, rm -rf and .env reads. Hooks and deny rules are not held back by the trust dialog. They applied in our claude -p tests, where the dialog never appears, which is what you want from a guardrail.

Want it set up for you? The Safe setup pack ships deny rules and hooks that are tested against 100 dangerous commands and 65 harmless ones.

Block the risky commands Hooks examples