Logo Vincent
Back to all posts

Claude Code /permissions: Fine-Grained Control Over What AI Can Do

Claude
Claude Code /permissions: Fine-Grained Control Over What AI Can Do
Table of Contents

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:

BehaviorMeaning
allowAuto-approve, no popup
denyReject outright, Claude Code won’t execute
askForce 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:

Rule Sources & Priority: 6 configuration sources from lowest to highest override priority

SourceFile PathDescription
User~/.claude/settings.jsonGlobal rules, affect all projects
Project<project>/.claude/settings.jsonProject-level, can be committed to Git
Local<project>/.claude/settings.local.jsonProject-level local, gitignored
CLI--allowedTools and similar flagsTemporarily specified
ManagedEnterprise managed settingsPushed by admins, highest priority
SessionYour choices in the current sessionOnly 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:

ModeBehavior
defaultStandard mode. Read operations auto-approve, writes and command execution prompt
planPlanning mode. Claude Code drafts a plan first, prompts before execution
acceptEditsAccept edits mode. File edits auto-approve, Bash commands still prompt
bypassPermissionsSkip 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:

Permission Check Flow: 7 validation steps from tool call to execution

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, like Edit, 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

  1. 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
  2. Periodically check your rule list with /permissions — over time, you may accumulate allow rules you no longer need
  3. Use managed settings in enterprise environments — admins can force-deny certain operations through managed settings for compliance
  4. 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.”

Related Articles

Claude Code Agent Loop: Dissecting the Heart of an AI Coding Assistant

How does Claude Code understand your requests, invoke tools, and self-recover step by step? A source-code deep dive into the Agent Loop's core architecture — streaming responses, parallel tool execution, auto-compaction, and error recovery.

Where Is Claude Code settings.json? 5 Config Files, 1 Priority Rule

Claude Code has 5 config file locations: user-level (~/.claude/), project-level (.claude/), local-only, CLI flags, and enterprise managed settings. Learn which file to use when, how priority works, and why your settings might be ignored.

Claude Code settings.json Permissions: Control Exactly What AI Can Do

Stop clicking 'Allow' on every action. Configure Claude Code's permissions system — set allow/deny/ask rules, use wildcards, control MCP tools, and protect sensitive directories. Every permission option with practical examples.

Claude Code settings.json Hooks: Auto-Run Scripts at Every Step

Want to auto-validate commands before they run? Send Slack notifications when tasks finish? Claude Code hooks let you inject custom scripts at key moments — PreToolUse, PostToolUse, Stop, Notification — with practical examples.

Claude Code settings.json: Copy-Paste Templates for env, model, auth & More

Ready-to-use Claude Code settings.json snippets for env vars, model switching, apiKeyHelper auth, git signing, effort level, language, auto-updates, and more. Every field includes a working JSON example you can copy and paste.

© 2026 vincentqiao.com . All rights reserved.