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
In this repository12 other files it gives its agents.
- englogSkill
- githubSkill
- git-repos-cleanupSkill
- gitSkill
- golang-developmentSkill
- pull-requestSkill
- python-developmentSkill
- review-claude-configSkill
- review-pull-requestSkill
- session-learningsSkill
- triage-dependency-prsSkill
- untracked-secrets-scanSkill
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
- Very specific: line 11
Before editing global settings, resolve ~/.claude/settings.json with readlink.
- Very specific: line 83
Read the global and repo CLAUDE.md files, then check every rule that restricts an action against the allow list.
- Distinctive: line 90
If CLAUDE.md explicitly allows something (e.g.
- Distinctive: line 104
Only flag keys you can confirm are wrong or duplicated.
- Distinctive: line 117
Use these when replacing wildcards.
- Distinctive: line 166
After presenting the report, ask: "Apply all?
- Very specific: line 169
Use targeted Edit calls per finding.
- Very specific: line 172
Do not create settings.json files that did not previously exist — if a repo has no .claude/settings.json, skip it.
- Distinctive: line 178
Never rewrite an entire settings file unless the user explicitly asks.
- Distinctive: line 179
Never silently remove a permission — always show the proposed change first.
- Distinctive: line 181
When in doubt about whether a permission is safe, flag it rather than silently keeping it.
≈ “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.
Files
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
- Global:
~/.claude/settings.json - Per-repo project settings:
.claude/settings.jsonunder the user-provided workspace root (all depths) - Per-repo local settings:
.claude/settings.local.jsonunder 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 | sortThen 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
| Pattern | Risk | Mitigation |
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 *) wildcard | Pre-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 *) wildcard | Pre-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
| Pattern | Risk | Mitigation |
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
| Pattern | Risk | Mitigation |
enableWeakerNetworkIsolation: true | Defeats 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 access | Reads 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 mergemay be allowed - "Always ask before posting to GitHub" → nothing matching
gh pr comment,gh issue commentorgh pr reviewmay 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 andskillOverrideskeys 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 (
voiceEnabledvsvoice.enabled). - Model settings: report
model,effortLevelandmodelSettings; flag per-model entries that repeat the global value or reference models no longer in use. - Validity:
jq -e .on every file. settings.local.jsonone-offs: it accumulates per-command approvals. Keep only general rules (preferences, accepted-risk destructive commands likerm:*, external writes likegh 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.
gitbecause it uses SSH remotes,ghbecause 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 subcommandsOmit 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.jsonwhen it is a symlink. - Use targeted
Editcalls 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.jsonfiles 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.jsonis 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.
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
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.

