11# Gatekeeper Plugin
22
3- Two-layer security for Claude Code: auto-approve safe commands, AI-assisted review for the rest .
3+ Three-tier security for Claude Code: auto-approve safe commands, block destructive ones, and AI-review everything in between — across all tools .
44
55## Overview
66
7- Gatekeeper eliminates repetitive permission dialogs for safe development commands while maintaining security against destructive operations.
7+ Gatekeeper eliminates repetitive permission dialogs for safe development commands while maintaining security against destructive operations. It covers ** all Claude Code tools ** (Bash, Write, Edit, WebFetch, and more), not just shell commands.
88
99### How It Works
1010
1111``` text
12- Bash command
12+ Any tool call ( Bash, Write, Edit, WebFetch, Read, etc.)
1313 │
1414 ▼
1515Layer 1: PreToolUse (pattern matching, <5ms)
16- ├── ALLOW: safe patterns (npm, git, node, etc.) → skip permission dialog
17- ├── DENY: destructive patterns (rm -rf /, mkfs, etc.) → block immediately
18- └── PASSTHROUGH: unknown commands → permission dialog
19- │
20- ▼
21- Layer 2: PermissionRequest (AI agent, opus)
22- ├── approve → execute
23- └── reject → block with reason
16+ ├── HARD DENY: destructive patterns → block immediately
17+ ├── SOFT DENY: risky but sometimes intended → passthrough to AI
18+ ├── ALLOW: safe patterns → skip permission dialog
19+ └── UNKNOWN: no matching rule → passthrough to AI
20+ │
21+ ▼
22+ Layer 2: PermissionRequest (AI agent, haiku)
23+ ├── "Did user explicitly request this?"
24+ │ ├── Yes → allow
25+ │ └── No → deny with reason
26+ └── Unsure → user sees permission prompt
2427```
2528
26- ## Allowed Patterns
29+ ### Decision Types
30+
31+ | Decision | Hook Output | Effect |
32+ | ----------| ------------| --------|
33+ | ** Hard Deny** | ` { permissionDecision: "deny" } ` | Tool blocked immediately, stderr message |
34+ | ** Soft Deny** | ` null ` (passthrough) | Proceeds to AI review in PermissionRequest |
35+ | ** Allow** | ` { permissionDecision: "allow" } ` | Tool executes, permission dialog skipped |
36+ | ** Unknown** | ` null ` (passthrough) | Proceeds to AI review (fail-open) |
37+
38+ ## Tool Coverage
39+
40+ ### Bash Commands
41+
42+ #### Hard Deny (absolute blocks)
43+
44+ | Pattern | Reason |
45+ | ---------| --------|
46+ | ` rm -rf / ` | Filesystem root deletion |
47+ | ` rm -rf /* ` | Destructive wildcard deletion from root |
48+ | ` rm -rf ~ ` | Home directory deletion |
49+ | ` mkfs.* ` | Disk format |
50+ | ` dd if=/dev/zero of=/dev/ ` | Disk zeroing |
51+ | ` node -e ` , ` python -c ` , etc. | Inline interpreter code execution |
52+ | ` find -exec/-execdir/-delete ` | Arbitrary command execution |
53+
54+ #### Soft Deny (AI reviews intent)
55+
56+ | Pattern | Reason |
57+ | ---------| --------|
58+ | ` git push --force ` | Force push needs user intent verification |
59+ | ` git push origin main ` | Push to default branch needs user intent verification |
60+ | ` git reset --hard ` | Hard reset needs user intent verification |
61+ | ` git clean -f ` | Git clean needs user intent verification |
62+ | ` git branch -D ` | Force branch delete needs user intent verification |
63+ | ` npm publish ` | Package publish needs user intent verification |
64+ | ` terraform apply/destroy ` | Infrastructure change needs user intent verification |
65+ | ` kubectl apply/delete ` | Kubernetes mutation needs user intent verification |
66+ | ` git commit --no-verify ` | Skipping commit verification needs user intent verification |
67+ | ` chmod 777 ` | Broad permission change needs user intent verification |
68+ | ` nc -l ` , ` python -m http.server ` | Exposing local service needs user intent verification |
69+ | ` crontab ` , ` systemctl enable ` | Unauthorized persistence needs user intent verification |
70+ | IAM/RBAC commands | Permission grant needs user intent verification |
71+
72+ #### Allowed (instant approve)
2773
2874| Category | Examples |
2975| ----------| ----------|
3076| Package managers | ` npm test ` , ` bun install ` , ` yarn add ` , ` pnpm run ` |
3177| Git read | ` git status ` , ` git log ` , ` git diff ` , ` git branch ` |
3278| Git write | ` git add ` , ` git commit ` , ` git merge ` , ` git pull ` |
33- | Git push | ` git push ` (non-force only ) |
79+ | Git push | ` git push ` (non-force, non-main ) |
3480| Build/runtime | ` node ` , ` npx ` , ` tsx ` , ` python ` , ` cargo build ` , ` make ` |
3581| File inspection | ` ls ` , ` cat ` , ` grep ` , ` find ` , ` tree ` , ` wc ` |
3682| Docker read | ` docker ps ` , ` docker logs ` , ` docker images ` |
3783
38- ## Denied Patterns
84+ ### Write/Edit
3985
40- | Pattern | Reason |
41- | ---------| --------|
42- | ` rm -rf / ` | Filesystem root deletion |
43- | ` rm -rf /* ` | Destructive wildcard deletion from root |
44- | ` rm -rf ~ ` | Home directory deletion |
45- | ` mkfs.* ` | Disk format |
46- | ` dd if=/dev/zero of=/dev/ ` | Disk zeroing |
86+ | Decision | Pattern | Reason |
87+ | ----------| ---------| --------|
88+ | Soft Deny | ` .env ` , ` .env.* ` | Secrets file |
89+ | Soft Deny | ` .claude/settings ` | Agent self-modification |
90+ | Soft Deny | ` CLAUDE.md ` | Agent self-modification |
91+ | Soft Deny | ` .github/workflows/* ` | CI/CD config |
92+ | Soft Deny | ` .gitlab-ci.yml ` , ` Jenkinsfile ` , ` .circleci/* ` | CI/CD config |
93+ | Allow | Project-relative paths | Safe project file |
94+ | Passthrough | Absolute paths outside project | AI review |
95+
96+ ### WebFetch
97+
98+ | Decision | Pattern | Reason |
99+ | ----------| ---------| --------|
100+ | Soft Deny | Paste services (pastebin, hastebin, etc.) | Data exfiltration risk |
101+ | Soft Deny | File sharing (transfer.sh, file.io, etc.) | Data exfiltration risk |
102+ | Soft Deny | Script downloads (` .sh ` , ` .bash ` , ` .ps1 ` ) | Code execution risk |
103+ | Allow | ` localhost ` , ` 127.0.0.1 ` | Safe dev server |
104+ | Passthrough | Other URLs | AI review |
105+
106+ ### Safe Tools (instant allow)
107+
108+ Read, Glob, Grep, LS, Search, TaskCreate, TaskUpdate, TaskList, TaskGet, TodoRead, TodoWrite, NotebookRead
109+
110+ ### Unknown Tools
111+
112+ All unrecognized tools pass through to the AI review layer (fail-open design).
113+
114+ ## AI Review (Layer 2)
115+
116+ The PermissionRequest hook uses an AI agent (haiku model) with rules derived from [ Claude Code's auto-mode classifier] ( https://www.anthropic.com/engineering/claude-code-auto-mode ) :
117+
118+ ** Core principle** : "Did the user explicitly request this action?"
119+
120+ The AI prompt covers 7 ALLOW rules and 25+ DENY rules including:
121+ - Data exfiltration and credential exposure
122+ - Supply chain attacks and untrusted code integration
123+ - Infrastructure mutations and production access
124+ - Agent self-modification and unauthorized persistence
125+ - External system writes and content fabrication
47126
48127## Installation
49128
@@ -64,19 +143,34 @@ bun run build
64143### Testing
65144
66145``` bash
146+ bun test
147+
148+ # Manual tests:
149+
150+ # HARD DENY test
151+ echo ' {"tool_name":"Bash","tool_input":{"command":"rm -rf /"}}' | node dist/pre-tool-use.js
152+
153+ # SOFT DENY test (no output = passthrough to AI)
154+ echo ' {"tool_name":"Bash","tool_input":{"command":"git push --force"}}' | node dist/pre-tool-use.js
155+
67156# ALLOW test
68157echo ' {"tool_name":"Bash","tool_input":{"command":"npm test"}}' | node dist/pre-tool-use.js
69158
70- # DENY test
71- echo ' {"tool_name":"Bash","tool_input":{"command":"rm -rf /"}}' | node dist/pre-tool-use.js
159+ # Safe tool ALLOW test
160+ echo ' {"tool_name":"Read","tool_input":{"file_path":"test.ts"}}' | node dist/pre-tool-use.js
161+
162+ # Write soft deny test (no output = passthrough to AI)
163+ echo ' {"tool_name":"Write","tool_input":{"file_path":".env"}}' | node dist/pre-tool-use.js
72164
73- # PASSTHROUGH test (no output)
74- echo ' {"tool_name":"Bash ","tool_input":{"command":"curl https://example.com" }}' | node dist/pre-tool-use.js
165+ # PASSTHROUGH test (unknown tool, no output)
166+ echo ' {"tool_name":"Agent ","tool_input":{}}' | node dist/pre-tool-use.js
75167```
76168
77169## References
78170
79- - [ Claude Code Tips: PermissionRequest Hook Pattern] ( https://www.threads.com/@boris_cherny/post/DUMZy85EoFj )
171+ - [ Anthropic: Claude Code Auto Mode] ( https://www.anthropic.com/engineering/claude-code-auto-mode )
172+ - [ Anthropic: Claude Code Sandboxing] ( https://www.anthropic.com/engineering/claude-code-sandboxing )
173+ - [ Claude Code Hooks Documentation] ( https://code.claude.com/docs/en/hooks )
80174
81175## License
82176
0 commit comments