Claude Code is Anthropic's official AI coding agent, used by developers at companies from startups to Fortune 500. Learn more →

Claude Code Configuration

How to Set Up Claude Code Permissions

Control exactly what Claude can and cannot do. From permission modes to allowed tools to directory access, here is everything you need to configure Claude Code safely.

Updated February 10, 2026 · 14 min read

Claude Code permissions are controlled through three modes (Default, Auto-accept Edits, and Plan Mode) plus allow/deny rules for specific tools and paths. You configure them in your settings files or toggle them live with Shift+Tab. Once set up, every session respects your rules automatically.

This guide covers all three permission modes, how to configure allowed and denied tools, directory access controls, and security best practices to keep your codebase safe.

What Are Claude Code Permissions?

Claude Code permissions control what actions Claude can take during a session. They work at two levels:

Together, these let you fine-tune Claude's behavior from fully autonomous to completely locked down, depending on your needs.

Why this matters: Get permissions right once, and every Claude session respects your rules automatically. No more approving the same safe commands repeatedly, and no more worrying about accidental access to sensitive files.

The Three Permission Modes

Claude Code has three main permission modes. Press Shift+Tab to cycle through them during a session.

Mode File Edits Shell Commands When to Use
Normal Asks permission Asks permission Default for most work
Auto-Accept Auto-approves Asks permission Trusted editing tasks
Plan Mode Blocked Blocked Analysis and planning only

Normal Mode (Default)

Claude asks for confirmation before every file edit and shell command. You see exactly what Claude wants to do and approve each action.

Use this when:

Auto-Accept Mode

Claude automatically applies file edits without asking, but still prompts before running shell commands. This speeds up editing workflows while maintaining safety for potentially destructive operations.

Use this when:

Note: Auto-Accept only auto-approves file edits. Shell commands, web fetches, and other tools still require confirmation unless you configure specific allow rules.

Plan Mode

Claude operates in read-only mode. It can read files, search code, and analyze your project, but cannot make any changes. Perfect for exploration and planning before execution.

Use this when:

Setting the Default Permission Mode

You can set your preferred starting mode in settings.json:

{
  "permissions": {
    "defaultMode": "acceptEdits"
  }
}

Available values:

You can also start Claude with a specific mode from the command line:

claude --permission-mode plan

Configuring Allowed and Denied Tools

Permission rules let you pre-approve safe operations and block dangerous ones. They go in your settings.json file.

Basic Structure

{
  "permissions": {
    "allow": [
      "Bash(npm run lint)",
      "Bash(npm run test *)",
      "Read(./src/**)"
    ],
    "deny": [
      "Bash(rm -rf *)",
      "Bash(curl *)",
      "Read(./.env)"
    ],
    "ask": [
      "Bash(git push *)"
    ]
  }
}

Rule Evaluation Order

Rules are checked in this order:

  1. Deny - If matched, block immediately (highest priority)
  2. Ask - If matched, prompt for confirmation
  3. Allow - If matched, proceed without asking

The first matching rule wins. A deny rule always takes precedence over an allow rule for the same pattern.

Permission Syntax

Format Example Matches
Tool only Bash or Bash(*) All Bash commands
Exact match Bash(npm run build) Only npm run build
Wildcard Bash(npm run *) npm run test, npm run lint, etc.
Path glob Read(./src/**) All files under ./src/

Wildcard tip: Space before * matters. Bash(ls *) matches ls -la but not lsof. Bash(ls*) matches both.

I documented my full permissions and security setup in a free guide — it covers everything from initial configuration to daily workflows.

Available Tools

Tool Permission Format Example
Bash Bash(command) Bash(npm run test *)
Read Read(path) Read(./.env)
Edit Edit(path) Edit(./src/**)
MultiEdit MultiEdit(path) MultiEdit(./src/**)
Write Write(path) Write(./src/**)
NotebookEdit NotebookEdit(path) NotebookEdit(./notebooks/**)
WebFetch WebFetch(domain:host) WebFetch(domain:github.com)
WebSearch WebSearch WebSearch
Task Task Task
MCP mcp__server__tool mcp__github__create_issue

Note: Glob, Grep, LS, and AskUserQuestion do not require permissions since they have no side effects.

Real-World Permission Examples

Safe Development Workflow

Allow common dev commands, block destructive operations:

{
  "permissions": {
    "allow": [
      "Bash(npm run *)",
      "Bash(yarn *)",
      "Bash(git status)",
      "Bash(git diff *)",
      "Bash(git log *)",
      "Bash(git add *)",
      "Bash(git commit *)",
      "Bash(* --version)",
      "Bash(* --help)"
    ],
    "deny": [
      "Bash(rm -rf *)",
      "Bash(git push --force *)",
      "Bash(git reset --hard *)",
      "Bash(curl *)",
      "Bash(wget *)"
    ],
    "ask": [
      "Bash(git push *)"
    ]
  }
}

Protect Sensitive Files

Block access to credentials and secrets:

{
  "permissions": {
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)",
      "Read(./**/credentials.json)",
      "Read(~/.aws/**)",
      "Read(~/.ssh/**)",
      "Edit(./.env)",
      "Edit(./.env.*)"
    ]
  }
}

Restrict to Source Code Only

Only allow edits within the src directory:

{
  "permissions": {
    "allow": [
      "Edit(./src/**)",
      "Edit(./tests/**)"
    ],
    "deny": [
      "Edit(./package.json)",
      "Edit(./package-lock.json)",
      "Edit(./.github/**)"
    ]
  }
}

Directory Permissions

By default, Claude Code can only access files within your current working directory. To allow access to related directories:

{
  "permissions": {
    "additionalDirectories": [
      "../docs/",
      "../shared-utils/",
      "~/templates/"
    ]
  }
}

This is useful for monorepos or when you need to reference files outside the current project.

Settings File Locations

Claude Code reads settings from multiple locations, with higher precedence settings overriding lower ones:

Scope Location Shared Use Case
Managed /etc/claude-code/ (Linux) or /Library/Application Support/ClaudeCode/ (macOS) Yes (IT) Organizational policies
User ~/.claude/settings.json No Personal preferences
Project .claude/settings.json Yes (git) Team standards
Local .claude/settings.local.json No (gitignored) Personal overrides

Managed settings have the highest precedence and cannot be overridden. Use these for enforcing company-wide policies.

The Dangerous Skip Permissions Flag

Claude Code has a flag for fully autonomous operation:

claude --dangerously-skip-permissions

This bypasses all permission checks. Claude runs commands without asking, edits files automatically, and operates completely unattended.

Warning: This flag is dangerous. Only use it in isolated environments like Docker containers without internet access. Never use it with production code, sensitive data, or when connected to external services.

You can disable this flag entirely for your organization:

{
  "permissions": {
    "disableBypassPermissionsMode": "disable"
  }
}

Security Best Practices

1. Start Restrictive, Open Up As Needed

Begin with Normal mode and minimal allow rules. Add permissions as you discover safe patterns in your workflow.

2. Always Deny Sensitive Files

Create deny rules for .env, credentials, API keys, and SSH keys. This protects against accidental exposure.

3. Use Project-Level Settings for Teams

Put team-agreed permissions in .claude/settings.json and commit it to git. Everyone gets the same safety rails.

4. Be Careful with Bash Wildcards

Bash patterns that constrain arguments are fragile. Bash(curl http://github.com/ *) will not match curl -X GET http://github.com/... because flags come before the URL.

5. Review Before Enabling Auto-Accept

Only use Auto-Accept mode when your code is version-controlled and you can easily revert unwanted changes.

Hooks: Automated Permission Enforcement

Claude Code supports lifecycle hooks that add another layer of control beyond static permission rules. Hooks are configured in your settings.json file and run custom scripts at key moments.

PreToolUse Hooks

PreToolUse hooks fire before Claude executes any tool. You can use them to modify tool inputs, inject additional context, or block execution entirely. This is useful for enforcing security policies automatically.

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          { "type": "command", "command": "~/.claude/hooks/validate-bash.sh" }
        ]
      }
    ]
  }
}

PostToolUse Hooks

PostToolUse hooks fire after a tool completes. Common uses include running linters after file edits and sending notifications after long operations.

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit",
        "hooks": [
          { "type": "command", "command": "npx prettier --write $CLAUDE_FILE_PATH" }
        ]
      }
    ]
  }
}

Key difference: Permission rules are static allow/deny lists. Hooks are dynamic scripts that can inspect the actual command or file path and make decisions programmatically. For most users, permission rules are sufficient. Hooks are for advanced control.

When to Use Each Mode

Scenario Recommended Mode Why
Learning a new codebase Plan Mode Read-only exploration is safe
Bug fixing with unclear scope Normal Mode Review each change carefully
Refactoring with clear plan Auto-Accept Speed up trusted edits
Running build/test scripts Normal + allow rules Pre-approve safe commands
Working with sensitive data Normal + deny rules Block access to secrets

Common Mistakes

  1. Overly broad allow rules: "allow": ["Bash"] allows any command. Be specific about what you are approving.
  2. Forgetting deny rules for secrets: Always explicitly deny .env and credential files, even if you think you will not ask Claude about them.
  3. Not using project settings: If you are on a team, share permissions via .claude/settings.json so everyone has the same safety configuration.
  4. Skipping Plan Mode for complex work: When making changes that touch many files, start in Plan Mode to understand the scope before executing.
  5. Using skip-permissions casually: The --dangerously-skip-permissions flag should only be used in isolated, throwaway environments.

FAQ

Can I have different permissions for different projects?

Yes. Put project-specific settings in .claude/settings.json within each project. These override your global user settings.

How do I see what permissions are active?

Run /permission in Claude Code to view current permission rules and their sources.

Do permissions apply to MCP tools?

MCP (Model Context Protocol) tools have their own permission system. Configure MCP permissions separately in your MCP server settings.

Can I reset to default permissions?

Delete your settings files and Claude Code returns to default behavior. User settings are at ~/.claude/settings.json.

What happens if allow and deny conflict?

Deny always wins. If a pattern matches both an allow and deny rule, the action is blocked.

Free: The AI Growth Breakdown

See how one business went from 0 to 600 daily visitors in 14 days using AI. The exact tools and results.

Get the Free Breakdown →

Keep reading