A permission hook for Claude Code with granular rule-based control. Provides fine-grained, context-aware permission decisions for Claude Code tool calls — allowing safe commands automatically while prompting or blocking risky ones.
Install as a Claude Code plugin:
claude plugin add npm:claude-permissions-hook
Or install from npm directly:
npm install -g claude-permissions-hook
The hook runs automatically as a Claude Code PreToolUse hook. It reads tool call details from stdin and returns a permission decision (allow, ask, or deny) on stdout.
# Test the hook manually
echo '{"session_id":"s","transcript_path":"/tmp/t","cwd":"/tmp","permission_mode":"default","hook_event_name":"PreToolUse","tool_name":"Bash","tool_input":{"command":"git status"},"tool_use_id":"t"}' | claude-permissions-hook hook --config my-config.kdl
The hook respects Claude Code's permission modes. allow and deny from config are absolute. ask is modulated by mode:
| Config Decision | bypassPermissions | dontAsk | default / plan / acceptEdits |
|---|---|---|---|
| allow | allow | allow | allow |
| deny | deny | deny | deny |
| ask | allow | deny | ask |
| unlisted | — | — | — |
Unlisted programs (not in any config list) return no opinion — Claude handles them natively.
The hook discovers your config automatically in this order:
--config /path/to/config.kdl (explicit CLI argument)$CLAUDE_PERMISSIONS_HOOK_CONFIG environment variable~/.config/claude-permissions-hook/config.kdl (XDG default)If no config is found, the hook returns ask for everything — prompting you to set one up.
# Explicit path
claude-permissions-hook hook --config ~/.config/claude-permissions.kdl
# Or set the environment variable
export CLAUDE_PERMISSIONS_HOOK_CONFIG=~/.config/claude-permissions.kdl
# Or place it in the default location
mkdir -p ~/.config/claude-permissions-hook
cp example-config.kdl ~/.config/claude-permissions-hook/config.kdl
bash {
allow "git" "cargo" "npm" "node" "ls" "cat" "echo"
deny "rm" "shutdown" "reboot"
ask "docker" "kubectl" "curl"
}
Lookup precedence: deny > ask > allow.
For chained commands (&&, ||, ;, |), the hook evaluates each program and takes the most restrictive decision. If any program is denied, the whole command is denied.
Without a config (no --config, no env var, no default file), the hook returns ask for everything, prompting you to set up a config file.
The hook evaluates programs by their actual name, unwrapping a small set of transparent launchers automatically:
| Transparent launchers |
|---|
command, env, nohup, exec, builtin |
For example, env TERM=xterm git status is evaluated as git, not env.
Limitation: Launchers not in this list (e.g. sudo, nice, time, xargs) are evaluated as the program name itself — the wrapped target is not inspected.
This means a config like:
bash {
allow "sudo"
deny "rm"
}
will allow sudo rm -rf / (evaluated as sudo, which is in the allow list) — the deny "rm" rule does not fire.
Guidance: Avoid pairing allow rules on unlisted launchers with deny rules on their potential targets. Either deny the launcher itself, or add the target explicitly:
bash {
deny "sudo" # block sudo entirely
deny "rm"
}
See CONTRIBUTING.md for development setup, running tests, and code style guidelines.
# Build
cargo build
# Run tests
cargo nextest run
# Lint
cargo clippy --all-targets
# Format
cargo fmt
Contributions are welcome! Please read CONTRIBUTING.md before submitting a pull request.
MIT — see LICENSE file.
Matches all tools
Hooks run on every tool call, not just specific ones
Own this plugin?
Verify ownership to unlock analytics, metadata editing, and a verified badge. GitHub access is read-only (username + org membership).
Sign in to claimOwn this plugin?
Verify ownership to unlock analytics, metadata editing, and a verified badge. GitHub access is read-only (username + org membership).
Sign in to claimBased on adoption, maintenance, documentation, and repository signals. Not a security audit or endorsement.
npx claudepluginhub nexaedge/claude-permissions-hookManage Cloudflare DNS zones and records through Terraform in the nexaedge/infrastructure repository. Automates the full workflow: edit Terraform files, open PR, review plan, merge, watch apply, and verify.
Vendored skills from external repositories
Spec-driven project execution pipeline — from ideation to verified deliverables, orchestrated by AI agents. Works with any project type.
Smart command safety filter for Claude Code — parses shell pipelines and evaluates per-command safety rules to auto-approve safe commands and block dangerous ones
PreToolUse hook that auto-approves safe Bash commands by parsing them into an AST and matching against configurable patterns
A secure runtime for Claude Code. Intercepts every tool call with policy-based allow/block/ask decisions, evasion detection, path fencing, file snapshots, and audit logging.
Auto-approve compound Bash commands (pipes, chains, subshells) by parsing each segment via shfmt AST and checking against allow/deny lists
Core skills library for Claude Code: TDD, debugging, collaboration patterns, and proven techniques
Harness-native ECC operator layer - 67 agents, 271 skills, 92 legacy command shims, reusable hooks, rules, selective install profiles, and production-ready workflows for Claude Code, Codex, OpenCode, Cursor, and related agent harnesses