# Claude Code Permission Wildcards: Use `:*` not `*`

**Category:** Configuration
**Difficulty:** Easy
**Impact:** High - Affects all permission patterns

## The Issue

When configuring Claude Code permissions in `.claude/settings.json`, wildcard patterns must use `:*` for prefix matching, not just `*`.

## Wrong ❌

```json
{
  "permissions": {
    "allow": [
      "Bash(git add *)",
      "Bash(ls *)",
      "Bash(gh pr view *)"
    ]
  }
}
```

## Correct ✅

```json
{
  "permissions": {
    "allow": [
      "Bash(git add :*)",
      "Bash(ls :*)",
      "Bash(gh pr view :*)"
    ]
  }
}
```

## Why This Matters

- **Validation fails**: `claude doctor` will report errors for incorrect wildcard syntax
- **Permissions won't work**: Patterns with `*` instead of `:*` may not match as expected
- **Silent failures**: Claude may request permission for commands you thought were allowed

## How to Detect

Run the diagnostic tool:

```bash
claude doctor
```

Look for errors like:

```
Invalid Settings
/path/to/.claude/settings.json
  └ permissions
    └ allow
      ├ "Bash(git add *)": Use ":*" for prefix matching, not just "*"
```

## How to Fix

### Manual Fix

Update each pattern in your settings files:
- Global: `~/.claude/settings.json`
- Project: `.claude/settings.json`
- Local: `.claude/settings.local.json`

### Automated Fix (bash)

```bash
# Fix project settings
sed -i.bak 's/"Bash(\([^)]*\) \*)"/"Bash(\1 :*)"/g' .claude/settings.json

# Fix global settings
sed -i.bak 's/"Bash(\([^)]*\) \*)"/"Bash(\1 :*)"/g' ~/.claude/settings.json

# Verify
python3 -m json.tool .claude/settings.json > /dev/null && echo "✓ Valid"
```

## Common Patterns to Fix

### Git Commands
- `Bash(git add *)` → `Bash(git add :*)`
- `Bash(git commit *)` → `Bash(git commit :*)`
- `Bash(git checkout *)` → `Bash(git checkout :*)`
- `Bash(git push origin *)` → `Bash(git push origin :*)`

### GitHub CLI
- `Bash(gh pr view *)` → `Bash(gh pr view :*)`
- `Bash(gh issue list *)` → `Bash(gh issue list :*)`
- `Bash(gh api *)` → `Bash(gh api :*)`

### System Commands
- `Bash(ls *)` → `Bash(ls :*)`
- `Bash(cat *)` → `Bash(cat :*)`
- `Bash(echo *)` → `Bash(echo :*)`

### Language Tools
- `Bash(npm install *)` → `Bash(npm install :*)`
- `Bash(pytest *)` → `Bash(pytest :*)`
- `Bash(poetry show *)` → `Bash(poetry show :*)`

## When `:*` is NOT Needed

Commands without arguments or with specific flags:

```json
{
  "permissions": {
    "allow": [
      "Bash(git status)",           // ✓ No wildcard needed
      "Bash(git diff)",             // ✓ No wildcard needed
      "Bash(npm run build)",        // ✓ Specific command
      "Bash(gh pr status)"          // ✓ No wildcard needed
    ]
  }
}
```

## Best Practices

1. **Always use `claude doctor`** before committing settings changes
2. **Use `:*` for prefix matching** when you want to allow any arguments
3. **Be specific when possible** - prefer `Bash(npm run test)` over `Bash(npm run :*)`
4. **Test after changes** - try the command to verify permissions work

## Related Documentation

- [Claude Code Permissions Guide](../../docs/claude-code-best-practices.md#permission-system)
- [Settings Configuration](../../.claude/README.md#configuration-architecture)

## Real-World Impact

In our Phase 1 automation foundation implementation, we had to fix ~90 permission patterns across:
- Global settings: `~/.claude/settings.json`
- Project settings: `.claude/settings.json`

The issue wasn't caught until running `claude doctor`, which could have caused silent permission failures during automated PR workflows.

## Lesson Learned

**Always run `claude doctor` as part of your CI/CD or pre-commit workflow** when managing Claude Code configurations in a repository. This is especially important when the repository itself is meant to be a template or knowledge base for others.
