Claude Code /permissions: Fine-Grained Control Over What AI Can Do
What is /permissions
If you’ve used Claude Code, you’ve definitely experienced this:
- Claude Code wants to run
npm install— a popup asks “Allow?” - You click Allow, then it wants to run
npm test— another popup - By the end of a task, you’ve clicked “Allow” a dozen times
The other extreme: you get tired of popups and enable bypass permissions mode — but feel uneasy, wondering what if it runs something dangerous?
/permissions solves exactly this problem. It gives you fine-grained control over every tool in Claude Code: which actions auto-approve, which must ask you first, and which are outright blocked.
Not too loose, not too tight — just right.
Permission System Basics
Before diving into /permissions, let’s understand Claude Code’s permission model.
Three Behaviors
Every permission rule maps to one of three behaviors:
| Behavior | Meaning |
|---|---|
| allow | Auto-approve, no popup |
| deny | Reject outright, Claude Code won’t execute |
| ask | Force a popup, even in permissive modes |
Rule Format
Permission rules use the format ToolName or ToolName(content):
Bash → allow/deny/ask all Bash commands
Bash(npm install) → only the exact "npm install" command
Bash(npm:*) → all commands starting with "npm" (prefix match)
Bash(npm *) → same, using wildcard syntax
Edit → all file edit operations
mcp__server1 → all tools from an MCP server
mcp__server1__tool1 → a specific MCP server tool
Rule Sources
Permission rules can come from multiple places, with later sources overriding earlier ones:
| Source | File Path | Description |
|---|---|---|
| User | ~/.claude/settings.json | Global rules, affect all projects |
| Project | <project>/.claude/settings.json | Project-level, can be committed to Git |
| Local | <project>/.claude/settings.local.json | Project-level local, gitignored |
| CLI | --allowedTools and similar flags | Temporarily specified |
| Managed | Enterprise managed settings | Pushed by admins, highest priority |
| Session | Your choices in the current session | Only valid for this session |
How to Use /permissions
In Claude Code’s interactive mode, type:
/permissions
An interactive panel appears listing all active permission rules. Its alias is /allowed-tools.
In this panel you can:
- View all allow, deny, and ask rules, along with which config source they come from
- Delete rules you no longer need
- Retry denied operations — if an action was previously denied, you can remove the restriction and retry here
Configuring Permissions in settings.json
The /permissions panel is great for viewing and deleting rules. But for bulk-adding rules, editing settings.json directly is more efficient.
Basic Structure
{
"permissions": {
"allow": ["Bash(npm:*)", "Bash(git:*)", "Edit", "Read", "Glob", "Grep"],
"deny": ["Bash(rm -rf:*)", "Bash(sudo:*)"],
"ask": ["Bash(git push:*)"]
}
}
Allow Rule Examples
{
"permissions": {
"allow": [
"Bash(npm:*)",
"Bash(npx:*)",
"Bash(node:*)",
"Bash(git:*)",
"Bash(ls:*)",
"Bash(cat:*)",
"Bash(echo:*)",
"Bash(mkdir:*)",
"Bash(cp:*)",
"Bash(mv:*)",
"Edit",
"Write",
"Read",
"Glob",
"Grep",
"WebFetch",
"WebSearch",
"Agent",
"TodoWrite",
"mcp__github"
]
}
}
The effect of these rules:
- Common dev commands (npm, git, node, file operations) auto-approve
- File read/write and search tools auto-approve
- All tools from the GitHub MCP server auto-approve
- Any unlisted operations still prompt for confirmation
Deny Rule Examples
{
"permissions": {
"deny": ["Bash(rm -rf:*)", "Bash(sudo:*)", "Bash(curl * | sh:*)", "Bash(wget * | sh:*)"]
}
}
These rules outright block dangerous operations: recursive deletion, sudo escalation, and downloading-and-executing scripts from the internet.
Ask Rule Examples
{
"permissions": {
"ask": ["Bash(git push:*)", "Bash(git checkout:*)", "Bash(docker:*)"]
}
}
These commands always prompt for confirmation even in permissive modes — pushing code, switching branches, and Docker operations are things you probably want to review.
Wildcard Matching Explained
Permission rules support three matching modes:
Exact Match
Bash(npm install)
Only matches the exact npm install command. npm install express won’t match.
Prefix Match (:* syntax)
Bash(npm:*)
Matches all commands starting with npm: npm install, npm test, npm run build all match.
This is the most common format. The :* after the prefix means “anything can follow.”
Wildcard Match (* syntax)
Bash(git * --force)
* can be placed anywhere, matching any content. The rule above matches git push --force, git push origin main --force, etc.
If your rule ends with space + * (like git *), then bare git itself also matches — consistent with prefix match behavior.
MCP Tool Matching
mcp__github → all tools from the GitHub MCP server
mcp__github__* → same, wildcard syntax
mcp__github__create_pr → only the create_pr tool
Permission Modes
Beyond rules, Claude Code has global “permission modes” that determine default behavior when no rule matches:
| Mode | Behavior |
|---|---|
| default | Standard mode. Read operations auto-approve, writes and command execution prompt |
| plan | Planning mode. Claude Code drafts a plan first, prompts before execution |
| acceptEdits | Accept edits mode. File edits auto-approve, Bash commands still prompt |
| bypassPermissions | Skip permissions. All operations auto-approve (dangerous, use with caution) |
Permission modes can be switched in /config or set as defaults in settings.json:
{
"permissions": {
"defaultMode": "default"
}
}
Permission Check Flow
When Claude Code wants to execute a tool, the complete permission check flow is:
Tool call request
|
Input validation (validateInput)
|
PreToolUse Hooks check
|
Permission rule matching
|-- Hit deny rule -> Reject
|-- Hit allow rule -> Approve
|-- Hit ask rule -> Prompt
+-- No rule match -> Check permission mode
|
Prompt user to choose
|-- Allow Once -> Approve this time
|-- Allow Always -> Add to allow rules
+-- Deny -> Reject
|
Tool-level check (checkPermissions)
|
Execute
Key points:
- Deny rules take priority over allow rules — if an action matches both allow and deny, deny wins
- Hooks are checked before rules — hooks can intercept or even modify tool calls
- Choosing “Allow Always” in the prompt automatically writes a rule — the same action won’t ask again
Practical Tips
Tip 1: Start Loose, Tighten Gradually
When you first start using Claude Code, don’t rush to configure permissions. Use default mode and observe which operations Claude Code needs day-to-day. Once you’ve built up experience, gradually add allow and deny rules based on your needs.
Selecting “Allow Always” in popups is the simplest way to add rules — over time, your permission configuration naturally fills out.
Tip 2: Use Layered Management
- Global rules (
~/.claude/settings.json) — Universal rules needed across all projects, likeEdit,Read,Glob,Grep - Project shared rules (
.claude/settings.json) — Team-unified project-level rules, like allowing project-specific build commands - Personal local rules (
.claude/settings.local.json) — Your personal preferences, like allowing tools only you use
Tip 3: Use Deny Rules as a Safety Net
Even if your allow rules are generous, add a few deny rules as a backstop:
{
"permissions": {
"deny": ["Bash(rm -rf /)", "Bash(sudo:*)", "Bash(:(){ :|:& };:)"]
}
}
Deny rules take priority over everything — they’re your last line of defense.
Tip 4: Use /permissions to Debug Permission Issues
If Claude Code keeps failing on a certain operation, or does something it shouldn’t, open /permissions to check the active rule list. Each rule shows its source (user / project / local / session), making it easy to identify which config file is causing the issue.
Security Recommendations
- Don’t put overly permissive allow rules in shared project settings.json — team members have different environments; commands you trust might be risky for others
- Periodically check your rule list with
/permissions— over time, you may accumulate allow rules you no longer need - Use managed settings in enterprise environments — admins can force-deny certain operations through managed settings for compliance
- Only use bypassPermissions mode when you fully trust the current task — it skips all prompts, including for dangerous operations
Final Thoughts
Permission management seems like a hassle, but it’s really the trust foundation for collaborating with AI.
If every action triggers a popup, you get interrupted and lose efficiency. If nothing triggers a popup, you worry and feel uneasy. Good permission configuration is the key to being both smooth and secure — auto-approve what’s safe, intercept what’s risky.
Spend ten minutes adding common operations to the allow list and dangerous operations to the deny list, then you can focus on what truly matters — letting Claude Code write code for you, instead of constantly clicking “Allow.”
More Articles
- Why AI-First Startups Only Need One Programming Language
- cc-ping: Ping All Your Claude Code Configs in One Command
- Shocking! This Tool Lets Programmers Finish 95 Minutes of Work in 4 Minutes! 24x Efficiency Boost
- CCBot - 24x Development Efficiency Boost
- Claude Code /add-dir: The Monorepo Command You Miss
- Claude Code Token-Saving Tip: The Power of the Exclamation Mark
- I Built a Bot That Runs Claude Code From Chat
- Claude Code /btw Command Explained: Quick Side Questions Without Breaking Flow
- Claude Code /compact: Free Up Context, Keep Progress
- Claude Code /config: Every Setting Explained
- Claude Code /context: What's Eating Your Context Window?
- Claude Code /diff: See Exactly What Changed, Turn by Turn
- Claude Code /fast: Same Opus, 2x Speed — Worth It?
- Best Practice for External Knowledge in Claude Code: GitHub MCP + Context7
- Claude Code /hooks: Make AI Follow Your Rules
- Claude Code /init: Generate CLAUDE.md in 10 Seconds
- Claude Code MCP: Give Your AI Access to Any Tool
- Claude Code /memory Explained: Make AI Truly Remember Your Project
- Claude Code /model: Opus vs Sonnet vs Haiku Guide
- Claude Code /plan Explained: Think Before You Code
- Claude Code + Playwright MCP: AI Can Finally "See" the Page
- Claude Code /resume Command Explained: Don't Let Your Conversations Go to Waste
- Claude Code /review: Let AI Do Your Code Review
- Claude Code Skills Explained: Build Your Custom Command Library
- Claude Code /stats: See How Much AI Does For You
- Claude Code /status Command Explained: Your Session Dashboard
- Claude Code /tasks Command Explained: Master Your Background Tasks
- Claude Code /usage Command Explained: Know Your Remaining Quota
- Claude Code /vim: Vim Keybindings in Your AI Coding Assistant
- Claude Code in 2026: The Only Setup Guide You Need
- The Complete Guide to Claude: From Chat to Code to Automation