Skip to content
Tips & Tricks
Claude Code

/permissions - Control What Tools Claude Code Can Use

Allow, deny, or gate specific tools and commands in Claude Code. Set boundaries per project so Claude works the way you want.

claude-codepermissionstoolssafetyconfigurationsettings

What is it

Claude Code comes with a bunch of built-in tools: it can read files, edit code, run shell commands, fetch web pages, and more. /permissions lets you control which of those tools Claude can use, and how. You can allow things automatically (no prompts), require approval every time, or block them entirely.

Think of it as a bouncer list for Claude's toolbox. You decide who gets in, who gets checked at the door, and who's banned.

Claude Code permissions docs

What problems it solves

You're working on a project with a production database config sitting in .env. Claude keeps asking to read it, and every time you have to say no. You want to just block it once so Claude stops trying.

Or you've got a team of developers using Claude Code, and you don't want anyone's Claude accidentally running git push --force or rm -rf on a shared repo. You need guardrails that apply to everyone, checked into version control.

Or you trust Claude to run your test suite and linter without asking every single time, but you still want a prompt before it touches anything else. Right now you're clicking "Yes" on npm test thirty times a day.

How to use it

Type /permissions in Claude Code to see the interactive UI. It shows all your current rules and where they come from.

Rules come in three flavors:

  • Allow: Claude uses the tool without asking. No prompt.
  • Ask: Claude asks for your approval each time. This is the default for most tools.
  • Deny: Claude can't use the tool at all. Blocked.

Rules are checked in order: deny wins over ask, ask wins over allow. If something is denied anywhere, nothing else can override it.

Quick setup via settings.json

The fastest way to set up rules is in your project's .claude/settings.json. This gets checked into version control so the whole team gets the same guardrails:

|.claude/settings.json
{
"permissions": {
  "allow": [
    "Bash(npm test *)",
    "Bash(npm run lint)",
    "Bash(git status)",
    "Bash(git diff *)"
  ],
  "deny": [
    "Bash(git push --force *)",
    "Bash(rm -rf *)",
    "Read(./.env)"
  ]
}
}

Rule syntax

Rules follow the format Tool or Tool(specifier):

|examples
Bash                         # All shell commands
Bash(npm run build)          # Exact command
Bash(npm run *)              # Wildcard, anything starting with "npm run "
Read(./.env)                 # Specific file
Edit(/src/**/*.ts)           # All TypeScript files under src/
WebFetch(domain:example.com) # Web requests to a specific domain

The wildcard * works like you'd expect. Bash(npm *) matches npm test, npm run build, etc. A space before the * matters: Bash(ls *) matches ls -la but not lsof.

Deny rules only apply to Claude's built-in tools, not to shell commands. Read(./.env) blocks Claude's Read tool but doesn't stop cat .env in Bash. If you need OS-level file protection, look into Claude Code's sandboxing feature.

Permission modes

You can also change Claude's overall permission mode with Shift+Tab during a session:

  • Default: prompts for file edits and commands
  • Accept Edits: auto-approves file edits, still asks for commands
  • Plan Mode: read-only, Claude can analyze but not change anything
  • Auto: evaluates actions with background safety checks (research preview)

Pro tips

When you approve a command with "Yes, don't ask again," it saves a permanent allow rule for that specific command in your project. These pile up over time. Run /permissions occasionally to audit what's been auto-allowed and clean up anything you don't want there anymore.

The dontAsk permission mode is great for CI/CD pipelines. It auto-denies everything except what you've explicitly allowed, so Claude can only run pre-approved commands. No human in the loop needed, and no surprise tool calls.

References