Claude Code commands

Control What Claude Code Can Do: Permissions

4 min read

The old advice that “Claude Code asks before it edits files” is no longer true by default. On Pro, Max and Team plans, interactive terminal sessions start in auto mode, where a classifier reviews actions instead of you and Claude edits most files and runs most commands without a prompt. On other plans, Manual mode is the starting point.

1. Check the mode you’re in

The status bar names it: ⏸ manual mode on, ⏵⏵ accept edits on, ⏸ plan mode on, ⏵⏵ auto mode on, ⏵⏵ bypass permissions on.

2. Cycle with Shift+Tab

From auto the first press goes to default, then the cycle runs default → acceptEdits → plan → back to default.

Set the starting mode with defaultMode in a settings file, or --permission-mode at launch.

3. Write rules that match

Rules are Tool or Tool(specifier). Memorize the wildcard trap: put the * after the subcommand. Bash(git log *) allows only git log; Bash(git *) allows every git command, git push included.

{
  "permissions": {
    "allow": ["Bash(npm run *)", "Bash(git commit *)", "Read", "Edit"],
    "deny": ["Bash(rm *)", "Read(./.env)", "Read(./.env.*)"]
  }
}

What it does: pre-approves npm scripts, commits and file access; refuses every rm and any read of your env files. Bash(ls:*) is another way to write Bash(ls *).

Note the deny rule is Bash(rm *), not Bash(rm -rf *): a narrower one is sidestepped by any other flag. Read and Edit rules use gitignore syntax, so Read(.env) matches at any depth.

4. Check what’s actually loaded

/permissions

What it does: lists every rule and the settings file it came from, and lets you add or remove one mid-turn. Which file to use is covered in Claude Code settings.json.

Verify it worked

Ask Claude to run one command you denied. It should refuse without prompting. If it asks instead, your rule didn’t match — rules are enforced by Claude Code, not by the model, so no amount of CLAUDE.md text changes what’s allowed. Real permissions beat instructions every time.

Next: work across a whole repo safely.

Source: Configure permissions.

Open the full interactive version (with copy buttons) ↗

← All guides