Troubleshooting12 min read

Permissions and Security - Troubleshooting

SFEIR Institute

TL;DR

Permission and security issues in Claude Code often block command execution, file access, or writing to certain directories. This troubleshooting guide provides diagnostic commands, probable causes, and concrete solutions to resolve each situation quickly.

Permission and security issues in Claude Code often block command execution, file access, or writing to certain directories. This troubleshooting guide provides diagnostic commands, probable causes, and concrete solutions to resolve each situation quickly.

Troubleshooting permissions and security in Claude Code is an essential skill for any developer who uses this tool daily. Claude Code manages three levels of permissions (read, write, and execute) that interact with the file system, Git, and your organization's security policies.

Permission misconfiguration is one of the most common sources of friction with Claude Code.

SFEIR Institute trainings

Claude Code Training

1 day · Fundamentals

View program

AI-Augmented Developer

2 days · Intermediate

View program

Before diving into each issue, here is a summary table of the 11 most common permission errors. This table lets you quickly identify your situation and apply the appropriate solution.

SymptomProbable CauseSolution
Permission denied when executing a Bash commandPermission mode too restrictive (plan mode)Switch out of plan mode with Shift+Tab into default or acceptEdits mode (--permission-mode acceptEdits), or approve the command manually
Unable to write to a project fileInsufficient system permissions on the directoryRun chmod -R u+w ./project on the affected folder
Claude Code refuses to run npm installCommand not authorized in the allowlistAdd the command in .claude/settings.json under permissions.allow (the --allowedTools flag grants the same allowance for a single session)
EACCES error during global installationnpm tries to write to /usr/local/lib without sudoConfigure the npm prefix: npm config set prefix ~/.npm-global
.env file ignored or inaccessible.claude/settings.json excludes sensitive filesCheck the deny rules in settings.json
git push blocked by Claude CodeSecurity policy prevents destructive actionsConfirm the action when the prompt appears or use --allowedTools
Sandbox blocks network accessSandbox mode enabled in your configurationDisable the sandbox by setting "sandbox": { "enabled": false } in settings.json, or toggle it in-session with /sandbox
Pre-commit hooks refusedClaude Code does not have permission to execute hooksMake the hook executable: chmod +x .git/hooks/pre-commit
Unable to read a file outside the projectDefault path restriction in Claude CodeAdd the path to the allow rules in settings.json
API key not recognized or expiredANTHROPIC_API_KEY variable missing or invalidExport the key: export ANTHROPIC_API_KEY=sk-ant-...
EPERM error on Windows/WSLPermission conflict between file systemsMove your project to the Linux filesystem (/home/user/)
Timeout during permission approvalWait time exceeded without user responsePre-approve frequent commands in the allow rules of settings.json

For an overview of permission mechanisms, consult the complete permissions and security guide that details each authorization level.

Key takeaway: identify the exact symptom in the table first before looking for a solution. Most issues are resolved in a couple of minutes once you know the cause.

How to diagnose a permission issue in Claude Code?

Diagnosis always starts with information gathering. Run these commands in order to understand the state of your environment.

# Check the Claude Code version
claude --version

# Display the active configuration
cat ~/.claude/settings.json

# Check the working directory permissions
ls -la .

# Test write permissions
touch .claude-test && rm .claude-test

The cat ~/.claude/settings.json command displays all active parameters, including permissions. In practice, most diagnoses are resolved by checking three elements: the installed version, directory permissions, and the active configuration.

Then check the main configuration file. This file is located in .claude/settings.json at your project root or in ~/.claude/settings.json for the global configuration.

{
 "permissions": {
 "allow": [
 "Read",
 "Write",
 "Bash(npm install)",
 "Bash(git status)"
 ],
 "deny": [
 "WebFetch"
 ]
 }
}

Specifically, if a command is missing from allowedTools and you are in restrictive mode, Claude Code will ask for manual approval on every execution. For deeper insights into common errors during your first sessions, the guide on common errors in first conversations covers the most frequent cases.

Key takeaway: run cat ~/.claude/settings.json first. This command reveals many issues.

Why does Claude Code refuse to execute certain commands?

Claude Code applies a three-layer security model: global permissions, project permissions, and dynamic approvals. A command can be blocked at any level.

The active permission mode determines the default behavior. Here are the concrete differences between each mode:

ModeCLI FlagBehaviorUse Case
default--permission-mode defaultAsks approval for each sensitive toolSecure daily use
acceptEdits--permission-mode acceptEditsAuto-approves file editsEveryday development
plan--permission-mode planAnalysis, plan before executionCode review, exploration
auto--permission-mode autoAuto-approves tool calls with background safety checksResearch preview. Auto-approves tool calls with background safety checks that verify actions align with your request
dontAsk--permission-mode dontAskPre-approved tools onlyRestricted execution
bypassPermissions--dangerously-skip-permissionsAll actions authorized without confirmationCI/CD, automated scripts

The default mode is recommended for the vast majority of enterprise use cases. In session, Shift+Tab or Alt+M cycles through modes. Check your active mode with the following command:

cat ~/.claude/settings.json | jq '.permissions'

If you receive the "Tool not allowed" error, it means the specific tool is not in your authorization list. Add it in your project configuration:

{
 "permissions": {
 "allow": [
 "Bash(npm install)",
 "Bash(npm test)",
 "Bash(git *)"
 ]
 }
}

The Bash(git *) syntax allows all Git commands in a single rule. In practice, this wildcard approach significantly reduces permission-related interruptions. To understand all available slash commands and their interactions with permissions, consult the guide on common slash command errors.

Key takeaway: the default mode (Normal) offers the best security/productivity trade-off. Only switch to --dangerously-skip-permissions in a controlled environment.

How to resolve file and directory access errors?

EACCES and Permission denied errors on files are among the most frequently reported issues. Here is how to diagnose and fix them.

Run this command to identify problematic files in your project:

# Find files that are not writable by the owner (portable across macOS and Linux)
find . -type f \( -name "*.ts" -o -name "*.json" \) ! -perm -u+w 2>/dev/null

There are three main causes. First, files cloned from a Git repository may retain restrictive permissions. Second, some editors lock open files. Third, CI/CD tools sometimes modify permissions after a build.

ScenarioDiagnostic CommandFix Command
Read-only filemacOS: stat -f "%Sp %N" file.ts / Linux: stat -c "%A %n" file.tschmod u+w file.ts
Locked .claude directoryls -la ~/.claude/chmod -R u+rw ~/.claude/
Corrupted node_modulesls -la node_modules/.package-lock.jsonrm -rf node_modules && npm install
Inaccessible CLAUDE.md filecat .claude/CLAUDE.mdchmod 644 .claude/CLAUDE.md

Specifically, after a git clone, systematically run chmod -R u+rw . on the project directory to avoid permission issues. This operation takes less than 2 seconds on a 500 MB project.

The CLAUDE.md memory system requires read and write permissions. If you encounter difficulties with this file, the guide on common CLAUDE.md memory system errors will help you resolve the issue.

Key takeaway: after every git clone, check permissions with ls -la. A preventive chmod -R u+rw . avoids many access errors.

How to configure security rules for a team project?

Security in Claude Code is configured at three levels: global (~/.claude/settings.json), project (.claude/settings.json), and session (CLI flags). Project rules take precedence over global rules.

Create a .claude/settings.json file at your project root with this structure:

{
 "permissions": {
 "allow": [
 "Read",
 "Edit",
 "Write",
 "Glob",
 "Grep",
 "Bash(npm test)",
 "Bash(npm run build)",
 "Bash(git add *)",
 "Bash(git commit *)"
 ],
 "deny": ["Bash(rm -rf *)", "Bash(git push --force)"]
 }
}

This configuration allows common development operations while blocking destructive actions. The deny list takes priority over the allow list: if a command appears in both, it will be rejected.

In practice, teams of 5 to 15 developers at SFEIR Institute use this configuration as a base, then adapt it to their specific needs. The permissions and security checklist provides a complete ready-to-use template.

To go further in mastering permissions, the one-day Claude Code training offered by SFEIR guides you through hands-on labs where you configure security policies tailored to your team context. You will learn to define granular rules and audit authorized actions.

Key takeaway: commit the .claude/settings.json file in your repository - the entire team then benefits from the same security rules.

What are the Git-specific permission issues in Claude Code?

Claude Code's Git integration applies additional safeguards. By default, Claude Code prompts for approval before running git commands that modify history or state (such as git push --force, git reset --hard, or git clean -f). These are not blocked outright: you can pre-authorize or deny them with permission rules in settings.json (for example, "deny": ["Bash(git push --force)"]).

Here are the most common Git-related permission errors:

  • git push requires manual confirmation on every execution unless pre-authorized in your permission rules
  • git commit --amend prompts for approval like any other state-modifying git command, unless pre-authorized in your permission rules
  • git checkout . prompts for approval before running, like other working-tree-modifying commands
  • Pre-commit hooks fail if the file is not executable

Check your Git hooks permissions with this command:

ls -la .git/hooks/

If a hook does not have the executable flag (-rw-r--r-- instead of -rwxr-xr-x), fix it with:

chmod +x .git/hooks/pre-commit
chmod +x .git/hooks/commit-msg

The Git integration troubleshooting guide covers advanced cases such as merge conflicts and rebase errors. If you encounter issues during initial installation, the installation troubleshooting guide addresses initial Git configuration errors.

Key takeaway: Git hooks must have the executable flag (chmod +x). This is the #1 cause of pre-commit failures in Claude Code.

How to resolve API key and authentication issues?

The Anthropic API key (ANTHROPIC_API_KEY) is the primary authentication mechanism for Claude Code. An invalid, expired, or misconfigured key blocks all functionality.

Verify that your key is correctly set:

# Check if the variable is set
echo $ANTHROPIC_API_KEY | head -c 10

# Test the connection
claude --print "test"

Anthropic API keys start with the sk-ant- prefix. If your key starts differently, it is invalid. API keys remain valid until they are revoked or deleted in the Anthropic Console.

IssueDiagnosisSolution
Key not setecho $ANTHROPIC_API_KEY returns emptyAdd export ANTHROPIC_API_KEY=sk-ant-... to ~/.zshrc
Key expired401 Unauthorized errorRegenerate a key on console.anthropic.com
Key revoked403 Forbidden errorContact your organization administrator
Quota exceeded429 Too Many Requests errorWait for quota reset or upgrade your plan

Usage is subject to your plan's rate limits. A 429 Too Many Requests error means you have reached that limit; check the official usage and limits documentation for the figures that apply to your plan.

For a quick start with a secure configuration, follow the permissions quickstart guide which includes API key configuration.

Key takeaway: store your API key in ~/.zshrc or a secrets manager - never hardcode it in a versioned file.

Can you customize permission levels per tool?

Claude Code allows you to define granular permissions for each tool individually. This feature is particularly useful when you want to allow certain Bash commands while blocking network tools.

The granular configuration uses the ToolName(pattern) syntax:

{
 "allow": [
 "Bash(npm test)",
 "Bash(npm run lint)",
 "Bash(npx jest *)",
 "Edit",
 "Read",
 "Write"
 ],
 "deny": [
 "Bash(curl *)",
 "Bash(wget *)",
 "WebFetch"
 ]
}

This approach allows test and lint commands while prohibiting outbound network requests. In practice, a large share of enterprise projects use this type of fine-grained configuration to comply with their network security policies.

The complete permissions tutorial guides you step by step through setting up these granular rules, with examples adapted to different project types (frontend, backend, monorepo).

If you are looking to deepen these security concepts in a broader framework, the 2-day AI-Augmented Developer training covers secure configuration of AI tools in professional environments, with workshops on team permission policies. For experienced profiles, the one-day AI-Augmented Developer - Advanced training covers advanced security strategies and permission audit automation.

Key takeaway: use the Bash(command) syntax to allow or block individual commands - granularity is the key to effective security.

When should you contact Anthropic support for a permission issue?

Certain issues go beyond the scope of local configuration. Contact Anthropic support in the following cases:

  1. Your API key returns a 403 error after regeneration
  2. The displayed quota does not match your plan
  3. A tool was working then stopped without any configuration change
  4. Permission errors appear only on certain machines with the same configuration
  5. --dangerously-skip-permissions mode does not work despite correct configuration

Before contacting support, gather this information:

# Generate a complete diagnostic report
claude --version
node --version
uname -a
cat ~/.claude/settings.json 2>&1
cat .claude/settings.json 2>/dev/null || echo "No project config"

When installing via npm, Node.js 18 or later is required. The native install does not depend on Node.js.

The general Claude Code troubleshooting guide centralizes diagnostic procedures for all issues, beyond permissions alone. Here is how to prepare your support request:

  • Include the complete output of claude --version and node --version
  • Attach your .claude/settings.json file (masking API keys)
  • Describe the exact steps to reproduce the issue
  • Specify whether the issue appeared after an update

Key takeaway: gather the Claude Code version, Node.js version, and your configuration before contacting support. These three elements significantly speed up diagnosis.

How to audit actions authorized and executed by Claude Code?

Claude Code records each action in a local journal. This journal lets you verify which commands were executed and which permissions were used.

To diagnose a problem, use /doctor in session or relaunch with --verbose. Session history is available in ~/.claude/projects/.

Each session records the tools used, commands executed, and results. In practice, this traceability is essential for enterprise compliance audits.

SFEIR recommends establishing a weekly session history review for sensitive projects. This practice takes 10 minutes and helps detect security policy deviations before they become incidents.

Key takeaway: use /doctor in session and review history in ~/.claude/projects/ for proactive permission auditing.

Recent articles about Claude

Claude Code Training

This topic is covered in Module 4 of our Claude Code training

Documentation, Organization and Prompt Management

1-day training • 60% hands-on labs • Expert instructors

View full program