# Permission Configuration

Claude Code uses a permission system to control which operations require user confirmation. Configuring permissions appropriately ensures both security and development efficiency.

## Four Permission Modes

| Mode | Description | Use Case |
|------|-------------|----------|
| `default` | Prompts for permission the first time a tool is used | Everyday development, balancing security and efficiency |
| `acceptEdits` | Automatically approves file edits; other operations still require confirmation | Tasks that involve frequent file modifications |
| `plan` | Analyze only, no execution (Plan Mode) | Exploring and reviewing code without wanting Claude to make any changes |
| `bypassPermissions` | Skip all permission prompts | CI/CD automation, trusted and secure environments |

### Switching Permission Modes

- Press **`Shift+Tab`** to cycle through permission modes
- Press **`Shift+Tab`** twice to enter Plan Mode (press Escape to exit)
- Select a mode directly from the dialog

## Configuring the Default Permission Mode

Configure in `.claude/settings.json`:

```json
{
  "permissions": {
    "defaultMode": "acceptEdits"
  }
}
```

## Allow Rules: Pre-approving Commands

Pre-approve specific commands to avoid being prompted every time:

```json
{
  "permissions": {
    "allow": [
      "Bash(npm run lint)",
      "Bash(npm run test:*)",
      "Bash(git status)",
      "Bash(git add:*)",
      "Bash(git diff:*)"
    ]
  }
}
```

**Allow rule syntax**:
- `Bash(command)` — exact command match
- `Bash(prefix:*)` — matches commands starting with the given prefix
- `Read(file path)` — allow reading a specific file
- `Write(file path)` — allow writing to a specific file

## Deny Rules: Protecting Sensitive Files

Prevent Claude from accessing or modifying sensitive files:

```json
{
  "permissions": {
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)",
      "Write(./.git/**)",
      "Bash(rm -rf:*)"
    ]
  }
}
```

**Deny rule syntax**:
- Path patterns support `*` (single level) and `**` (multiple levels) wildcards
- Deny rules take **higher priority** than Allow rules

## Using Allow and Deny Together

```json
{
  "permissions": {
    "defaultMode": "acceptEdits",
    "allow": [
      "Bash(npm run *)",
      "Bash(git status)",
      "Bash(git diff)"
    ],
    "deny": [
      "Bash(git push:*)",
      "Bash(rm -rf:*)",
      "Read(./.env*)"
    ]
  }
}
```

## Configuration File Hierarchy

Claude Code merges permission configurations in the following priority order:

| Priority | Location | Scope |
|----------|----------|-------|
| Highest | `.claude/settings.local.json` (not committed to Git) | Personal local overrides |
| Middle | `.claude/settings.json` (committed to Git) | Shared team configuration |
| Lowest | `~/.claude/settings.json` | Global user configuration |

**Team collaboration tips**:
- Put team-wide allow/deny rules in `.claude/settings.json` and commit it to Git
- Put personal-specific settings in `.claude/settings.local.json` and add it to `.gitignore`

## Best Practices

**1. Protect sensitive credentials**
```json
{
  "permissions": {
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./credentials/**)",
      "Read(./.ssh/**)"
    ]
  }
}
```

**2. Frontend project configuration**
```json
{
  "permissions": {
    "defaultMode": "acceptEdits",
    "allow": [
      "Bash(npm run dev)",
      "Bash(npm run build)",
      "Bash(npm run test:*)",
      "Bash(npm run lint:*)"
    ]
  }
}
```

**3. CI/CD automation**
```json
{
  "permissions": {
    "defaultMode": "bypassPermissions"
  }
}
```

> ⚠️ **Warning**: `bypassPermissions` mode skips all security checks. Only use it in fully trusted automated environments.