Claude-skill-registry claude-settings-expert

Expert on Claude Code settings.json configuration, permissions, sandbox, environment variables, and settings hierarchy. Triggers when user mentions settings.json, permissions, allow rules, deny rules, sandbox, hooks configuration, or settings precedence.

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/claude-settings-expert" ~/.claude/skills/majiayu000-claude-skill-registry-claude-settings-expert-ffa9ec && rm -rf "$T"
manifest: skills/data/claude-settings-expert/SKILL.md
source content

Claude Code Settings Expert

Purpose

Provide expert guidance on configuring Claude Code through settings.json, including permissions, hooks, sandbox configuration, environment variables, and settings hierarchy. Auto-invokes when users need help with settings.

When to Use

Auto-invoke when users mention:

  • Settings files - "settings.json", "configure", "configuration"
  • Permissions - "allow", "deny", "ask", "permissions", "permission rules"
  • Hooks - "hooks configuration", "PreToolUse hooks", "PostToolUse hooks"
  • Sandbox - "sandbox settings", "sandboxing", "filesystem isolation"
  • Environment - "environment variables", "env", "$CLAUDE_PROJECT_DIR"
  • Hierarchy - "settings precedence", "user settings", "project settings"

Knowledge Base

  • Official docs:
    .claude/skills/ai/claude-code/docs/code_claude_com/docs_en_settings.md
  • IAM docs: Look for IAM/permissions documentation
  • Hooks docs:
    .claude/skills/ai/claude-code/docs/code_claude_com/docs_en_hooks.md

Settings File Locations

Hierarchy (highest to lowest precedence)

  1. Enterprise managed policies

    • macOS:
      /Library/Application Support/ClaudeCode/managed-settings.json
    • Linux/WSL:
      /etc/claude-code/managed-settings.json
    • Windows:
      C:\ProgramData\ClaudeCode\managed-settings.json
    • Cannot be overridden by users
  2. Command line arguments

    • Temporary overrides for specific session
    • Example:
      claude --dangerously-skip-permissions
  3. Local project settings

    • .claude/settings.local.json
    • Personal project settings (not committed)
    • Git-ignored automatically
  4. Shared project settings

    • .claude/settings.json
    • Team-shared settings in source control
    • Committed to repository
  5. User settings

    • ~/.claude/settings.json
    • Personal global settings
    • Apply to all projects

When to Use Each

User settings (

~/.claude/settings.json
):

  • Personal preferences across all projects
  • Personal API keys
  • Personal slash commands
  • Personal output style

Project settings (

.claude/settings.json
):

  • Team permissions
  • Project-specific hooks
  • Required plugins/marketplaces
  • Team workflow configuration

Local project (

.claude/settings.local.json
):

  • Personal project overrides
  • Experimental settings
  • Local-only preferences
  • Not shared with team

Process

1. Identify Need

Ask clarifying questions:

What would you like to configure?

1. **Permissions** - Allow/deny specific tools or commands
2. **Hooks** - Automate tool execution workflows
3. **Sandbox** - Enable filesystem/network isolation
4. **Environment** - Set environment variables
5. **Plugins** - Configure plugins and marketplaces
6. **Model** - Override default model
7. **Other** - Company announcements, cleanup, etc.

2. Determine Scope

Ask about scope:

Where should this configuration apply?

- **User-level** (`~/.claude/settings.json`) - All your projects
- **Project-level** (`.claude/settings.json`) - This project, shared with team
- **Local** (`.claude/settings.local.json`) - This project, just you

3. Build Configuration

Based on needs, construct the appropriate JSON:

Permission Configuration

Structure

{
  "permissions": {
    "allow": ["permission-rule"],
    "ask": ["permission-rule"],
    "deny": ["permission-rule"],
    "additionalDirectories": ["../path"],
    "defaultMode": "default" | "plan" | "acceptEdits" | "bypassPermissions",
    "disableBypassPermissionsMode": "disable"
  }
}

Permission Rules

Tool-specific:

{
  "permissions": {
    "allow": [
      "Read(~/.zshrc)",
      "Bash(git diff:*)",
      "Bash(npm run lint:*)",
      "Bash(npm run test:*)"
    ],
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)",
      "Bash(curl:*)",
      "WebFetch",
      "WebSearch"
    ]
  }
}

Bash permissions:

  • Use prefix matching (not regex)
  • Bash(git:*)
    - All git commands
  • Bash(git diff:*)
    - Only git diff commands
  • Can be bypassed (not for security, use sandbox for that)

Read/Write permissions:

  • Read(./secrets/**)
    - Recursive pattern
  • Read(./.env)
    - Specific file
  • Write(./dist/**)
    - Allow writes to dist

Permission modes:

  • default
    - Ask for permission
  • plan
    - Plan mode (no execution without approval)
  • acceptEdits
    - Auto-approve edits only
  • bypassPermissions
    - Approve all (dangerous)

Example: Secure Development

{
  "permissions": {
    "allow": [
      "Bash(git status:*)",
      "Bash(git diff:*)",
      "Bash(git log:*)",
      "Bash(npm run lint:*)",
      "Bash(npm run test:*)",
      "Read(~/.gitconfig)"
    ],
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)",
      "Read(./config/credentials.json)",
      "Bash(curl:*)",
      "Bash(wget:*)",
      "Bash(rm -rf:*)",
      "WebFetch",
      "WebSearch"
    ],
    "defaultMode": "default"
  }
}

Hooks Configuration

Structure

{
  "hooks": {
    "EventName": [
      {
        "matcher": "ToolPattern",
        "hooks": [
          {
            "type": "command" | "prompt",
            "command": "bash command",
            "prompt": "LLM prompt with $ARGUMENTS",
            "timeout": 60
          }
        ]
      }
    ]
  },
  "disableAllHooks": false
}

Example: Auto-Format and Validate

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/format.sh",
            "timeout": 30
          }
        ]
      }
    ],
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/validate-bash.py"
          }
        ]
      }
    ],
    "UserPromptSubmit": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/add-context.sh"
          }
        ]
      }
    ]
  }
}

Sandbox Configuration

Structure

{
  "sandbox": {
    "enabled": true | false,
    "autoAllowBashIfSandboxed": true | false,
    "excludedCommands": ["git", "docker"],
    "allowUnsandboxedCommands": true | false,
    "network": {
      "allowUnixSockets": ["~/.ssh/agent-socket"],
      "allowLocalBinding": true | false,
      "httpProxyPort": 8080,
      "socksProxyPort": 8081
    },
    "enableWeakerNestedSandbox": false
  }
}

Example: Strict Sandbox

{
  "sandbox": {
    "enabled": true,
    "autoAllowBashIfSandboxed": true,
    "excludedCommands": ["docker"],
    "allowUnsandboxedCommands": false,
    "network": {
      "allowUnixSockets": ["/var/run/docker.sock"],
      "allowLocalBinding": true
    }
  },
  "permissions": {
    "deny": [
      "Read(.envrc)",
      "Read(~/.aws/**)",
      "Read(./secrets/**)"
    ]
  }
}

Notes:

  • Filesystem access via Read/Write/Edit deny rules
  • Network access via WebFetch allow/deny rules
  • macOS/Linux only (not Windows)

Environment Variables

Structure

{
  "env": {
    "KEY": "value",
    "NODE_ENV": "production",
    "API_URL": "https://api.example.com"
  }
}

Common Variables

{
  "env": {
    "ANTHROPIC_MODEL": "claude-sonnet-4-5-20250929",
    "DISABLE_TELEMETRY": "1",
    "DISABLE_AUTOUPDATER": "1",
    "DISABLE_PROMPT_CACHING": "0",
    "MAX_THINKING_TOKENS": "10000",
    "BASH_DEFAULT_TIMEOUT_MS": "120000"
  }
}

Plugin Configuration

Structure

{
  "enabledPlugins": {
    "plugin-name@marketplace-name": true | false
  },
  "extraKnownMarketplaces": {
    "marketplace-name": {
      "source": {
        "source": "github" | "git" | "directory",
        "repo": "org/repo",
        "url": "https://git.example.com/repo.git",
        "path": "/local/path"
      }
    }
  }
}

Example: Team Plugins

{
  "enabledPlugins": {
    "code-formatter@company-tools": true,
    "deployment@company-tools": true,
    "security-scanner@company-tools": false
  },
  "extraKnownMarketplaces": {
    "company-tools": {
      "source": {
        "source": "github",
        "repo": "company/claude-plugins"
      }
    }
  }
}

Other Settings

Model Override

{
  "model": "claude-sonnet-4-5-20250929"
}

Cleanup Period

{
  "cleanupPeriodDays": 20
}

Company Announcements

{
  "companyAnnouncements": [
    "Welcome to Acme Corp! Review code guidelines at docs.acme.com",
    "Reminder: Code reviews required for all PRs"
  ]
}

Force Login Method

{
  "forceLoginMethod": "console",
  "forceLoginOrgUUID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

API Key Helper

{
  "apiKeyHelper": "/bin/generate_temp_api_key.sh"
}

Disable Co-Authored-By

{
  "includeCoAuthoredBy": false
}

Status Line

{
  "statusLine": {
    "type": "command",
    "command": "~/.claude/statusline.sh"
  }
}

Output Style

{
  "outputStyle": "Explanatory"
}

Complete Example: Enterprise Project

{
  "permissions": {
    "allow": [
      "Bash(npm run:*)",
      "Bash(git status:*)",
      "Bash(git diff:*)",
      "Bash(git log:*)",
      "Bash(docker ps:*)",
      "Bash(kubectl get:*)"
    ],
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)",
      "Read(./config/production.json)",
      "Bash(curl:*)",
      "Bash(wget:*)",
      "Bash(git push:*)",
      "WebFetch",
      "WebSearch"
    ],
    "ask": [
      "Bash(git add:*)",
      "Bash(git commit:*)",
      "Write(./src/**)"
    ],
    "defaultMode": "default",
    "disableBypassPermissionsMode": "disable"
  },
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/lint-and-format.sh",
            "timeout": 60
          }
        ]
      }
    ],
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/validate-bash.py"
          }
        ]
      }
    ]
  },
  "sandbox": {
    "enabled": true,
    "autoAllowBashIfSandboxed": true,
    "excludedCommands": ["docker", "kubectl"],
    "network": {
      "allowUnixSockets": ["/var/run/docker.sock"],
      "allowLocalBinding": true
    }
  },
  "env": {
    "NODE_ENV": "development",
    "DISABLE_TELEMETRY": "1"
  },
  "enabledPlugins": {
    "security-scanner@company-tools": true,
    "code-quality@company-tools": true
  },
  "extraKnownMarketplaces": {
    "company-tools": {
      "source": {
        "source": "github",
        "repo": "company/claude-plugins"
      }
    }
  },
  "companyAnnouncements": [
    "Welcome to Company Dev! See docs.company.com for coding standards",
    "Reminder: All PRs require security scan approval"
  ],
  "model": "claude-sonnet-4-5-20250929",
  "cleanupPeriodDays": 20,
  "includeCoAuthoredBy": true
}

Validation

Check JSON Syntax

# Validate JSON
cat .claude/settings.json | jq .

# Pretty-print
cat .claude/settings.json | jq . > temp.json && mv temp.json .claude/settings.json

Test Configuration

# Start Claude Code with debug
claude --debug

# Check settings loaded
# Look for: "Loading settings from..."

Verify Permissions

# Run /permissions in Claude Code
/permissions

# Check what's allowed/denied

Troubleshooting

Settings Not Applied

Check:

  1. JSON syntax is valid (
    jq
    validation)
  2. File location is correct
  3. Restart Claude Code after changes
  4. Check precedence (higher-level settings override)

Permission Rules Not Working

Check:

  1. Rule syntax:
    Tool(pattern)
  2. Case-sensitive tool names
  3. Bash uses prefix matching (not regex)
  4. Precedence: deny > ask > allow

Hooks Not Running

Check:

  1. disableAllHooks
    is not
    true
  2. Hook configuration is valid
  3. Script has execute permissions
  4. Restart Claude Code
  5. Use
    /hooks
    to verify loaded

Sandbox Issues

Check:

  1. macOS/Linux only (not Windows)
  2. Docker/Podman installed
  3. Permissions for Docker socket
  4. Check
    excludedCommands
    for needed tools

Best Practices

DO:

✅ Use project settings for team configuration ✅ Use local settings for personal overrides ✅ Validate JSON syntax before committing ✅ Document why rules exist (comments via tools) ✅ Test settings before sharing with team ✅ Use specific permission rules ✅ Set appropriate timeouts for hooks ✅ Use

$CLAUDE_PROJECT_DIR
in hooks

DON'T:

❌ Commit sensitive data to project settings ❌ Use

bypassPermissions
mode in shared config ❌ Make permission rules too broad ❌ Forget to restart after changes ❌ Use hardcoded paths in hooks ❌ Disable all hooks globally without reason ❌ Override enterprise managed settings (you can't)

Sensitive Files

Exclude from Claude Code

{
  "permissions": {
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./.envrc)",
      "Read(./secrets/**)",
      "Read(./.aws/**)",
      "Read(./config/credentials.json)",
      "Read(./config/production.json)",
      "Read(./.ssh/**)",
      "Read(./build/**)",
      "Read(./dist/**)",
      "Read(./node_modules/**)"
    ]
  }
}

Settings Merging

Settings from different levels are merged:

Example:

User settings:

{
  "permissions": {
    "allow": ["Read(~/.gitconfig)"]
  }
}

Project settings:

{
  "permissions": {
    "deny": ["Read(./.env)"]
  }
}

Merged result:

{
  "permissions": {
    "allow": ["Read(~/.gitconfig)"],
    "deny": ["Read(./.env)"]
  }
}

Arrays are concatenated, objects are merged.

Interactive Configuration

Offer to create/update settings:

I can help you configure this. Would you like me to:

1. Create a new settings.json file
2. Update existing settings.json
3. Show you what to add manually

Where should I make these changes?
- User settings (~/.claude/settings.json)
- Project settings (.claude/settings.json)
- Local settings (.claude/settings.local.json)

Resources

  • Official Settings Docs:
    .claude/skills/ai/claude-code/docs/code_claude_com/docs_en_settings.md
  • Hooks Reference:
    .claude/skills/ai/claude-code/docs/code_claude_com/docs_en_hooks.md
  • Sandbox Guide: Look for sandboxing documentation
  • IAM Guide: Look for permissions documentation