agentleFS
jmlrtjmlrt/skills/review-claude-settings/SKILL.md

review-claude-settings

Skill0 starsChanged 4 months agoMITView on GitHub

Audit Claude Code settings.json files — global (~/.claude/settings.json) and per-repo (.claude/settings.json, .claude/settings.local.json) — for security risks, CLAUDE.md policy conflicts, stale entries, and permission consolidation. Use whenever the user asks to review, audit, validate, clean up, trim, or modernize Claude Code settings or permissions, asks "anything to update in my config", or asks about settings for a new model or Claude Code version.

  • Reads credentials
  • Deletes or force-pushes
  • Commits and pushes

The file

We split this skill into the rules it gives an agent

11 rules. About 0 are common, 7 are distinctive, and 4 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈7

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 4

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Before editing global settings, resolve ~/.claude/settings.json with readlink.

    line 11
  2. Very specific:

    Read the global and repo CLAUDE.md files, then check every rule that restricts an action against the allow list.

    line 83
  3. Distinctive:

    If CLAUDE.md explicitly allows something (e.g.

    line 90
  4. Distinctive:

    Only flag keys you can confirm are wrong or duplicated.

    line 104
  5. Distinctive:

    Use these when replacing wildcards.

    line 117
  6. Distinctive:

    After presenting the report, ask: "Apply all?

    line 166
  7. Very specific:

    Use targeted Edit calls per finding.

    line 169
  8. Very specific:

    Do not create settings.json files that did not previously exist — if a repo has no .claude/settings.json, skip it.

    line 172
  9. Distinctive:

    Never rewrite an entire settings file unless the user explicitly asks.

    line 178
  10. Distinctive:

    Never silently remove a permission — always show the proposed change first.

    line 179
  11. Distinctive:

    When in doubt about whether a permission is safe, flag it rather than silently keeping it.

    line 181

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Review Claude Settings

Audits all settings.json / settings.local.json files and produces a structured findings report. Changes require explicit confirmation before applying.

Before editing global settings, resolve ~/.claude/settings.json with readlink. If it is a symlink, edit its target rather than the symlink.

Scope

  1. Global: ~/.claude/settings.json
  2. Per-repo project settings: .claude/settings.json under the user-provided workspace root (all depths)
  3. Per-repo local settings: .claude/settings.local.json under the user-provided workspace root (all depths) — machine-local, never committed

Phase 1: Discovery

Run in parallel:

# Find all project settings files
find <workspace-root> -maxdepth 5 -name "settings.json" -path "*/.claude/*" 2>/dev/null | sort
find <workspace-root> -maxdepth 5 -name "settings.local.json" -path "*/.claude/*" 2>/dev/null | sort

Then read all discovered files in parallel, including the global settings file.


Phase 2: Consolidation Analysis

Compare permissions across all files to identify:

Should be global — a permission appears in 3+ repos, or is clearly tool-agnostic (e.g. Bash(grep *), Bash(jq *), Bash(ls *), Bash(git log *), Bash(gh pr list *)). Flag for promotion to global settings.json; then remove from each repo file.

Duplicates global — permission already present verbatim in the global file. Remove from the repo file.

Repo-specific — permission only makes sense in this specific repo (e.g. Bash(terraform plan *), Bash(aws ecs *), cloud-provider CLI calls). Keep in repo file.

settings.local.json entries — review whether they're truly machine-local or accidentally one-off approvals. If they enumerate individually approved specific invocations (e.g. Bash(git push origin feature-x:*)) rather than general rules, flag as stale.


Phase 3: Security Audit

Apply this checklist to the global settings file first, then each repo file.

Critical risks — pre-approve with no argument restriction

PatternRiskMitigation
Bash(cat *)Reads any file on disk, bypassing tool path restrictions (for example, credential files or .env).Remove; use the agent's scoped file-reading tool.
Bash(git *) wildcardPre-approves git push --force, git reset --hard, git clean -fdx, git config --global. CLAUDE.md policy says "never push without explicit instruction".Replace with enumerated safe subcommands (see safe list below).
Bash(gh *) wildcardPre-approves gh pr merge, gh pr comment, gh api *, gh repo delete, gh secret set. CLAUDE.md policy says "always ask before posting to GitHub".Replace with enumerated read-only subcommands (see safe list below).
Bash(find *)-exec flag turns find into an arbitrary command executor.Remove from global; add specific Bash(find <path> -name * -type *) patterns at repo level if needed.

High risks — wildcard over a powerful tool

PatternRiskMitigation
Bash(make *)Runs arbitrary Makefile targets in any repo — could trigger deploys, destructive clean operations, or custom targets.Replace with explicit safe targets: make build, make check, make clean, make fmt, make generate, make help, make lint, make test.
Bash(curl *)Exfiltrates data or calls external APIs without review. Combine with excludedCommands bypass makes it fully unsandboxed.Move to repo-level with specific target restrictions; or require prompt.
Bash(python3 *) / Bash(node *)Executes arbitrary scripts.Move to repo-level only.

Medium risks

PatternRiskMitigation
enableWeakerNetworkIsolation: trueDefeats sandbox network isolation — allows outbound connections beyond allowedDomains.Remove unless strictly required; document why if kept.
Bash(sed *)In-place editing of any file (sed -i). Lower risk since Edit tool is preferred, but worth reviewing.Acceptable if Read path restrictions are enforced; lower priority.
Bash(uv *)Can install packages and modify environment. Acceptable for Python development but check scope.Move to repo-level if only needed in Python repos.
Broad workspace read accessReads every repository in the workspace.Acceptable only when no narrower scope fits.

Policy vs permission gap check

For each of the following CLAUDE.md policies, verify no permission pre-approves the contradicted action:

Read the global and repo CLAUDE.md files, then check every rule that restricts an action against the allow list. Wildcards count: Bash(gh pr *) pre-approves gh pr merge and gh pr comment. Examples:

  • "Never merge via CLI" → nothing matching gh pr merge may be allowed
  • "Always ask before posting to GitHub" → nothing matching gh pr comment, gh issue comment or gh pr review may be allowed
  • "No secrets in code or commits" → no credential-exposing commands like Bash(env) with no path restriction
  • Deny rules must not block actions CLAUDE.md prescribes (e.g. git push --force* also blocks --force-with-lease)

If CLAUDE.md explicitly allows something (e.g. "git push is allowed in sandbox"), treat it as intentional and do not flag it.


Phase 3b: Hygiene

  • Stale skill references: compare Skill(...) allow entries and skillOverrides keys against the skills actually available in the session. Flag names that no longer exist and near-matches that look renamed. Flag a skill that is both allowed and "off".
  • Duplicate or legacy keys: e.g. a flat key that duplicates a nested one (voiceEnabled vs voice.enabled).
  • Model settings: report model, effortLevel and modelSettings; flag per-model entries that repeat the global value or reference models no longer in use.
  • Validity: jq -e . on every file.
  • settings.local.json one-offs: it accumulates per-command approvals. Keep only general rules (preferences, accepted-risk destructive commands like rm:*, external writes like gh api:*); flag specific commands and one-off paths for removal.

Only flag keys you can confirm are wrong or duplicated; never invent setting names.

excludedCommands review

excludedCommands bypasses the sandbox entirely (no network or filesystem restrictions). Any command listed here can reach any network host and read/write any file. Review each entry:

  • Is it intentionally trusted (e.g. git because it uses SSH remotes, gh because it uses GitHub API)?
  • Does the corresponding Bash(cmd *) allow list entry stay within the spirit of that trust?

Phase 4: Safe Permission Reference Lists

Use these when replacing wildcards.

gh read-only subcommands (safe to pre-approve globally):

"Bash(gh issue list *)", "Bash(gh issue view *)",
"Bash(gh pr checks *)", "Bash(gh pr diff *)", "Bash(gh pr list *)", "Bash(gh pr view *)",
"Bash(gh release list *)", "Bash(gh release view *)",
"Bash(gh repo list *)", "Bash(gh repo view *)",
"Bash(gh run list *)", "Bash(gh run view *)", "Bash(gh run watch *)",
"Bash(gh status *)",
"Bash(gh workflow list *)", "Bash(gh workflow view *)"

git safe subcommands (safe to pre-approve globally — excludes push/reset/clean/config):

"Bash(GIT_EDITOR=true git rebase *)",
"Bash(git add *)", "Bash(git blame *)", "Bash(git branch *)",
"Bash(git cherry-pick *)", "Bash(git checkout *)", "Bash(git commit *)",
"Bash(git describe *)", "Bash(git diff *)", "Bash(git fetch *)",
"Bash(git log *)", "Bash(git merge *)", "Bash(git remote *)",
"Bash(git rev-parse *)", "Bash(git show *)", "Bash(git stash *)",
"Bash(git status *)", "Bash(git submodule *)", "Bash(git switch *)",
"Bash(git tag *)", "Bash(git worktree *)"

make safe targets (safe to pre-approve globally):

"Bash(make build *)", "Bash(make check *)", "Bash(make clean *)",
"Bash(make fmt *)", "Bash(make generate *)", "Bash(make help *)",
"Bash(make lint *)", "Bash(make test *)"

Phase 5: Report

Present findings as numbered bullets (no tables) before any changes, grouped under Critical / High / Medium / Hygiene / Consolidation. Each bullet: file + line, the entry, the risk in one clause, the proposed fix.

### Critical
1. global:21 `Bash(gh pr *)` pre-approves `gh pr merge` → replace with read-only gh pr subcommands

Omit empty categories.


Phase 6: Apply (with confirmation)

After presenting the report, ask: "Apply all? Or specify which numbers to apply."

  • For global changes, edit the target of ~/.claude/settings.json when it is a symlink.
  • Use targeted Edit calls per finding; do not rewrite entire files.
  • Re-read each edited section after applying to confirm the change landed.
  • Auto mode may deny edits to permissions/sandbox sections as self-modification. Don't retry or work around it; finish the other edits, then give the user the exact replacement JSON for each blocked change.
  • Do not create settings.json files that did not previously exist — if a repo has no .claude/settings.json, skip it.

Constraints

  • Never rewrite an entire settings file unless the user explicitly asks.
  • Never silently remove a permission — always show the proposed change first.
  • settings.local.json is machine-local; never commit it; treat stale one-off entries as low priority unless the user asks to clean them up.
  • When in doubt about whether a permission is safe, flag it rather than silently keeping it.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.