- Rust 98.4%
- Shell 0.9%
- Dockerfile 0.7%
Auto-Mode rolled out to personal Max plans today, removing the last remaining reason to keep claude-permit alive. Updated README banner and POST-MORTEM status line with the lay-to-rest date. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .cargo | ||
| .claude-plugin | ||
| .devcontainer | ||
| bin | ||
| defaults | ||
| devwork | ||
| hooks | ||
| src | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| CLAUDE.md | ||
| POST-MORTEM.md | ||
| README.md | ||
⚠️ Archived — laid to rest 2026-04-29
claude-permit is no longer actively maintained. On March 24, 2026, Anthropic released Auto-Mode for Claude Code, which solves the same core problem — eliminating permission fatigue without sacrificing safety. With Auto-Mode now available on personal Max plans as of 2026-04-29, there is no remaining reason to keep building this. See the post-mortem for a full comparison, lessons learned, and ideas I think Anthropic should borrow.
claude-permit
Smart permission hook for Claude Code. Auto-approves safe operations, blocks dangerous ones, and uses an LLM to evaluate the gray area — eliminating most manual permission prompts while maintaining security.
Tool Call
│
├─ PreToolUse ──── Deny rules → BLOCK (<1ms, regex)
│ Allow rules → PERMIT
│ No match → pass through to Claude Code's built-in permissions
│ │
├─ PermissionRequest ────────────┘ (only if Claude Code would prompt)
│ LLM scores GREEN → auto-approve
│ LLM scores YELLOW → ask user (uncertain)
│ LLM scores RED → auto-deny
│
└─ PostToolUse ── Log outcome to audit trail
Every decision is logged. Review the audit log to promote patterns into deterministic rules. Over time the LLM tier fires less and less.
Requirements
- Claude Code CLI installed and authenticated
- Rust toolchain (for building from source) — or use the prebuilt Linux binary
Quick Start
1. Clone and build
git clone https://github.com/user/claude-permit.git
cd claude-permit
# Build from source
cargo build --release
cp target/release/claude-permit bin/
# Or use the prebuilt binary (Linux x86-64 only)
ls bin/claude-permit
2. Create default config
./bin/claude-permit setup
This creates ~/.claude/claude-permit/ with:
config.toml— deny/allow rules you can customizepolicy.md— the safety policy sent to the LLM for ambiguous cases
3. Install as a Claude Code plugin
From within a Claude Code session:
/plugins:add /path/to/claude-permit
Or load for a single session:
claude --plugin-dir /path/to/claude-permit
4. Verify
./bin/claude-permit validate
# Config valid: 9 deny rules, 0 ask rules, 11 allow rules
That's it. Start using Claude Code normally — the hook handles permissions automatically.
How It Works
Three tiers evaluate every tool call:
| Tier | Hook | Speed | What it does |
|---|---|---|---|
| 1 | PreToolUse | <1ms | Regex rules: deny dangerous patterns, allow known-safe ones |
| 2 | PermissionRequest | ~500ms | LLM (Haiku) scores ambiguous cases as GREEN/YELLOW/RED |
| 3 | PostToolUse | <1ms | Logs the outcome for audit |
The LLM tier only fires when a tool call (a) isn't matched by any rule AND (b) would normally prompt you for permission. The LLM call uses claude --print --model haiku with your existing Claude subscription — no separate API key needed.
Fail-open by design: if the hook errors for any reason, it passes through to normal Claude Code behavior. You're never blocked by a bug in the hook.
Configuration
Config lives at ~/.claude/claude-permit/config.toml. Rules use TOML literal strings (single quotes) so regex backslashes Just Work.
Deny rules (checked first, always win)
# Block catastrophic rm
[[deny]]
tool = 'Bash'
[deny.fields]
command = 'rm\s+.*-rf\s+(/|~|\$HOME)'
# Block force push
[[deny]]
tool = 'Bash'
[deny.fields]
command = 'git\s+(push\s+.*--force|reset\s+--hard)'
# Block credential files from any tool
[[deny]]
tool = '.*'
[deny.fields]
file_path = '\.(pem|key|secret|credentials)$'
Allow rules (checked second)
# All read-only tools
[[allow]]
tool = 'Read|Glob|Grep'
# Safe shell commands
[[allow]]
tool = 'Bash'
[allow.fields]
command = '^(ls|cat|head|tail|wc|pwd|which|date|echo|file|stat)\b'
# Git read operations
[[allow]]
tool = 'Bash'
[allow.fields]
command = '^git\s+(status|log|diff|show|branch)\b'
Key concepts
tool— regex matched against the tool name (e.g.Bash,Read,mcp__.*)fields— key-value pairs where each value is a regex matched against the corresponding field in the tool's input. ForBash, that'scommand. ForRead/Write/Edit, that'sfile_path.- Deny > Allow — deny rules are checked first and always take precedence
- Command chain awareness — for Bash, the rule engine parses
&&,||,;, pipes, and subshells, evaluating each command segment independently
See devwork/docs/config-spec.md for the full schema reference.
Auto-Promotion
When the LLM scores a tool call GREEN, claude-permit can automatically generate a deterministic allow rule so the LLM is never called again for that exact pattern. This is enabled by default for Write, Edit, and MultiEdit tools.
[auto_promote]
enabled = true
eligible_tools = 'Write|Edit|MultiEdit'
auto_rules_file = '~/.claude/claude-permit/auto-rules.toml'
Auto-generated rules are saved separately and merged on startup. Review them with the /audit skill or edit the file directly.
Audit Log
Every decision is logged to ~/.claude/claude-permit/audit.jsonl in JSONL format:
{"timestamp":"2026-03-26T10:15:03Z","hook":"pre_tool_use","tool":"Bash","decision":"allow","rule":"allow[4]","input_preview":"git status"}
{"timestamp":"2026-03-26T10:15:05Z","hook":"pre_tool_use","tool":"Write","decision":"passthrough","input_preview":"src/main.rs"}
{"timestamp":"2026-03-26T10:15:05Z","hook":"permission_request","tool":"Write","decision":"allow","llm_score":"GREEN","reasoning":"Writing to a project source file..."}
See devwork/docs/audit-spec.md for the full log format.
LLM Safety Policy
The policy document at ~/.claude/claude-permit/policy.md defines the scoring framework sent to Haiku:
- GREEN — safe, auto-approve (read ops, project file writes, dev tool commands)
- YELLOW — ambiguous, ask the user (system config changes, unfamiliar tools)
- RED — dangerous, auto-deny (destructive ops, credential access, remote code execution)
Edit this file to adjust the LLM's judgment criteria. See devwork/docs/llm-policy.md for the full policy.
Commands
claude-permit setup # Create default config + policy files
claude-permit validate # Validate config and show rule counts
claude-permit pre-tool-use # Handle PreToolUse hook (reads stdin)
claude-permit permission-request # Handle PermissionRequest hook (reads stdin, calls LLM)
claude-permit post-tool-use # Handle PostToolUse hook (reads stdin, logs outcome)
All hook commands read JSON from stdin and are invoked automatically by Claude Code's plugin system — you don't call them manually.
File Layout
~/.claude/claude-permit/
config.toml # Your rules (deny/allow + settings)
policy.md # LLM safety policy (editable)
audit.jsonl # Audit log (auto-created)
auto-rules.toml # Machine-generated rules from auto-promotion
Development
cargo test # Run all 101 tests
cargo build # Debug build
cargo build --release && cp target/release/claude-permit bin/ # Release build
The project uses a devcontainer with Rust toolchain, rust-analyzer, and Claude Code pre-installed. Open in VS Code or GitHub Codespaces for a batteries-included dev environment.
Documentation
| Document | Contents |
|---|---|
devwork/docs/architecture.md |
Hook flow, three-tier pipeline, interaction with settings.json |
devwork/docs/config-spec.md |
Full TOML config schema and all matchable fields |
devwork/docs/llm-policy.md |
The safety policy sent to Haiku |
devwork/docs/audit-spec.md |
JSONL audit log format and review workflow |
License
MIT