SSkilltecabyclaudinhocode
Enviar skill
← Voltar para o catálogo

permissions-audit

Segurança

Scope ('global'/'project'/'all') or 'discover <tool-name>' to explore a CLI tool's commands

2estrelas
Ver no GitHub ↗Autor: volleioLicença: MIT

Audit Claude Code permission allow/deny/ask lists across all settings files. Classify issues by risk, suggest tightening, and interactively apply fixes. Can also discover permissions for new CLI tools.

Mode Selection

Parse the first argument to determine the mode:

  • global, project, all, or no argument → Audit mode (Phases 1-4 below)
  • discover <tool-name>Discover mode (see Discover Mode section at the end)

Permission Model Reference

Claude Code has three permission arrays, evaluated in order: deny → ask → allow. First match wins.

ArrayBehavior
allowAuto-approved — no prompt
askAlways prompts for confirmation
denyAuto-rejected — tool cannot be used at all

Anything not matching any array falls through to the defaultMode setting. Use the right array for the intent:

  • allow — safe, read-only, or frequently-used commands (linters, test runners, git log)
  • ask — commands that should succeed but need human review each time (git commit, git push, deployments)
  • deny — commands that should never execute, even if explicitly requested (force push, rm -rf /)

Phase 1: Discovery

Read all three settings files and detect the project type.

Settings Files

Read each file. If a file doesn't exist, note it and continue.

  1. Global: ~/.claude/settings.json
  2. Project shared: .claude/settings.json (in project root)
  3. Project local: .claude/settings.local.json (in project root)

Extract permissions.allow, permissions.deny, and permissions.ask arrays from each. Also note the permissions.defaultMode value if set — it affects the overall security posture (see below). Ignore all other fields (env, hooks, model, statusLine, spinnerVerbs, etc.) — they are out of scope and must never be modified.

Default Mode Check

Read permissions.defaultMode from each file. Surface the value in the Phase 4 summary. Flag if set to a permissive mode:

ModeRiskNote
"default" or absentOKStandard behavior — prompts on first use
"plan"OKRequires plan approval
"dontAsk"OKAuto-denies unless pre-approved in allow rules
"bypassPermissions"CRITICALAll permission rules are ignored — every tool auto-approved
"acceptEdits"HIGHFile edits auto-approved without review

Do not modify defaultMode — only surface it as informational context.

Project Type Detection

Check for indicator files in the project root to determine project type(s). A project can have multiple types.

IndicatorType
pyproject.toml + uv.lockPython/uv
pyproject.toml + poetry.lockPython/Poetry
pyproject.toml (no uv.lock or poetry.lock)Python (generic)
requirements.txt or setup.py (no pyproject.toml)Python (pip)
package.json + package-lock.jsonNode/npm
package.json + yarn.lockNode/yarn
package.json + pnpm-lock.yamlNode/pnpm
package.json + bun.lock or bun.lockbNode/bun
Cargo.tomlRust
go.modGo
pom.xmlJava/Maven
build.gradle or build.gradle.ktsJava/Gradle
*.csproj or *.slnC#/.NET
GemfileRuby
composer.jsonPHP
*.tf filesTerraform
mise.toml or .mise.tomlMise
docker-compose.yml or docker-compose.yaml or compose.ymlDocker
.github/ directoryGitHub
MakefileMake

If mise is detected, run mise tasks ls to enumerate available task names. These feed into Phase 3 suggestions.

Scope Filtering

If the argument is one of the audit scopes:

  • global — only audit ~/.claude/settings.json
  • project — only audit .claude/settings.json and .claude/settings.local.json
  • all (default) — audit all three files

No Project Directory

If run outside a project (no .claude/ directory in the working directory), gracefully skip project settings files and only audit the global settings. Note this in the Phase 4 summary. Project-type detection and project-type-aware suggestions are also skipped in this case.

Phase 2: Audit

Analyze every entry in every allow/deny/ask list. Classify each finding by risk level.

Risk Levels

RiskCriteriaExamples
CRITICALAllows arbitrary execution or data destruction (in allow/ask)Bash(*), Bash(sudo *), Bash(rm -rf *), credentials in patterns
HIGHBroad wildcard on risky command family (in allow/ask)Bash(docker compose *), Bash(find *), Bash(git *)
MEDIUMDeprecated syntax, broader than necessary, duplicates, built-in overlap:* patterns, redundant entries, Bash(grep *)
LOWHygiene/informationalStale WebFetch domains, subset duplicates, style inconsistencies

Note: Broad patterns in deny are safety features, not risks — see check 1 for array-context-aware classification.

Checks to Perform

Run every check below against every entry. One entry can trigger multiple findings. When multiple checks flag the same entry, consolidate into a single finding using the highest severity and combining the rationale (e.g., an entry that is both overly permissive and in the wrong array → one finding, not two).

1. Overly Permissive Patterns

Flag entries in allow or ask that grant broad access to command families with known destructive subcommands. Skip this check for deny entries — broad patterns in deny are safety features, not risks.

PatternRisk (in allow)Risk (in ask)Why
Bash(*)CRITICALHIGHAllows any command
Bash(sudo *)CRITICALHIGHRoot access
Bash(rm -rf *)CRITICALHIGHArbitrary deletion
Bash(docker compose *) or Bash(docker compose:*)HIGHMEDIUMIncludes down -v, rm, exec
Bash(find *) or Bash(find:*)HIGHMEDIUM-exec allows arbitrary execution
Bash(git *) or Bash(git:*)HIGHMEDIUMIncludes destructive ops (reset, clean, push --force)
Bash(npm *) or Bash(npm:*)HIGHMEDIUMnpm exec allows arbitrary execution
Bash(PGPASSWORD=* psql *) or Bash(PGPASSWORD=* psql:*)CRITICALCRITICALArbitrary SQL execution. If password is a literal (not *), also a credential exposure issue (see check 4)
Bash(terraform *) or Bash(terraform:*)HIGHMEDIUMterraform apply, terraform destroy can modify/delete infrastructure
Bash(kubectl *) or Bash(kubectl:*)HIGHMEDIUMkubectl delete, kubectl exec can destroy resources or run arbitrary commands
Bash(make *) or Bash(make:*)HIGHMEDIUMMake targets are arbitrary shell commands — equivalent to Bash(*) for that target
Bash(yarn *) or Bash(yarn:*)HIGHMEDIUMyarn dlx allows arbitrary execution; yarn run can execute any package.json script
Bash(pnpm *) or Bash(pnpm:*)HIGHMEDIUMpnpm dlx/pnpm exec allows arbitrary execution; same risk profile as npm/yarn

Risk is lower in ask (user still confirms each use) but broad ask patterns still warrant tightening.

2. Deprecated Syntax

The legacy :* suffix syntax is deprecated. The current syntax uses a space: *.

  • Bash(cmd:*) should be Bash(cmd *)
  • Word boundary semantics: Bash(ls *) matches ls -la but NOT lsof. Bash(ls*) matches both.
  • Flag ALL :* entries as MEDIUM risk

Caution — commands with literal colons: Many tools use colons in their command names: mise tasks (mise run fe:lint), Maven goals (mvn dependency:tree), npm scripts (npm run build:prod), Laravel artisan (php artisan migrate:fresh), Rake tasks (rake db:migrate), Gradle subprojects (gradle :app:build). A pattern like Bash(npm run build:*) looks like it should match npm run build:prod, but Claude Code interprets the trailing :* as the deprecated wildcard suffix — maki

Como adicionar

/plugin marketplace add volleio/claude-permissions-audit

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Comentários · Nenhum comentário

Entre para comentar. Entrar

  • Ainda não há comentários. Seja o primeiro.