Claude Code Permissions: settings.json and allowedTools

Configure what Claude Code is allowed to do: restrict shell commands, limit file access, set up per-project permissions, and use allowedTools in CLI mode.

💥 50p impulse-buy: Power Prompts PDF (first 10 buyers) 30 battle-tested Claude Code prompts · 8-page PDF · paste into CLAUDE.md and never re-type a prompt again · 50p impulse-buy, no commitment

Claude Code uses a tiered permission system to control what tools Claude can invoke. Understanding the layers lets you run sessions that are both safe and friction-free.

Permission tiers

MethodScopeSyntax
Interactive promptSingle tool call (y/n)Runtime dialog
--allowedTools CLI flagOne sessionclaude --allowedTools "Read,Grep,Bash(git:*)"
.claude/settings.jsonProject (all sessions)JSON config
~/.claude/settings.jsonGlobal (all projects)JSON config

settings.json structure

// .claude/settings.json
{
  "permissions": {
    "allow": [
      "Read",
      "Grep",
      "Glob",
      "Bash(git status)",
      "Bash(git diff*)",
      "Bash(git log*)",
      "Bash(npm run *)",
      "Bash(pytest *)",
      "Edit",
      "Write"
    ],
    "deny": [
      "Bash(rm -rf*)",
      "Bash(curl*)",
      "Bash(wget*)"
    ]
  }
}

Tool specifier syntax

# Allow a specific tool (all uses):
"Read"

# Allow Bash with a prefix filter (glob):
"Bash(git *)"        # any git command
"Bash(npm run *)"    # npm run only (not npm install)
"Bash(pytest*)"      # any pytest invocation

# Allow specific file patterns for Edit:
"Edit(src/**)"       # edits inside src/ only

# Deny takes precedence over allow:
# If a command matches both allow and deny, it is denied.

Read-only session (safe for exploration)

# Only allow non-mutating tools:
claude --allowedTools "Read,Grep,Glob,Bash(git log*),Bash(git diff*),Bash(git status)"

# Or via CLI flag shorthand for a one-liner audit:
claude --print "Summarize the authentication system"   --allowedTools "Read,Grep,Glob"

CI / automation session (no interactive prompts)

# settings.json for a CI context — allow tests + read, deny all writes:
{
  "permissions": {
    "allow": [
      "Read", "Grep", "Glob",
      "Bash(pytest *)",
      "Bash(npm test)",
      "Bash(go test *)"
    ],
    "deny": ["Edit", "Write", "Bash(git commit*)", "Bash(git push*)"]
  }
}

Protecting sensitive files via hooks

// .claude/settings.json
{
  "permissions": {
    "allow": ["Edit"]
  },
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit",
        "hooks": [
          {
            "type": "command",
            "command": "if echo "$CLAUDE_TOOL_INPUT_FILE_PATH" | grep -qE '\.(env|pem|key)$|secrets/|credentials'; then echo 'Blocked: sensitive file' >&2; exit 2; fi"
          }
        ]
      }
    ]
  }
}

Project vs global settings precedence

# Resolution order (highest to lowest priority):
# 1. CLI flags (--allowedTools, --dangerouslySkipPermissions)
# 2. .claude/settings.json (project-level)
# 3. ~/.claude/settings.json (user global)
# 4. Built-in defaults (prompt for anything not listed)

# Tip: put team-wide permissions in .claude/settings.json (commit it).
# Put personal preferences in ~/.claude/settings.json (don't commit).

For hook-based blocking patterns (blocking individual file paths, blocking specific commands), see Claude Code hooks tutorial. For a complete command reference, see Claude Code slash commands.

Frequently asked questions

How do I restrict which tools Claude Code can use?
Use the --allowedTools CLI flag for one-off sessions, or configure permissions in .claude/settings.json for persistent project-level rules. The permissions key lists tools Claude can use without asking.
Where is Claude Code's settings.json?
Project settings: .claude/settings.json (relative to your project root). Global settings: ~/.claude/settings.json. Project settings override global settings for the same keys.
How do I allow Claude Code to run npm commands without asking?
Add Bash(npm:*) to your permissions array in .claude/settings.json. This allows any Bash command starting with 'npm' without a permission prompt.
Can I block Claude Code from editing certain files?
Yes. Use a PreToolUse hook that exits with code 2 when CLAUDE_TOOL_INPUT_FILE_PATH matches a protected path. Hooks are more flexible than static permissions for path-based blocking.
What is the difference between allowedTools and permissions in Claude Code?
--allowedTools is a CLI flag for a single session. permissions in settings.json is persisted and applies to all sessions in that project. Both accept the same tool specifier syntax (e.g., Bash(git:*), Edit, Read).

Free tools

Cost Calculator → API Cookbook → Diff Summarizer → Skills Browser →

More examples

Claude API Python QuickstartClaude API Node.js / TypeScript QuickstartClaude API Streaming in PythonClaude API Streaming in Node.js / TypeScriptClaude API Tool Use in PythonClaude API Tool Use in Node.js / TypeScript