No description
  • Rust 98.4%
  • Shell 0.9%
  • Dockerfile 0.7%
Find a file
Jochem de Boer 46c1721974 docs(archive): mark project laid to rest 2026-04-29
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>
2026-04-29 15:08:41 +02:00
.cargo feat(hooks): move LLM to PreToolUse + auto-promote GREEN decisions 2026-03-02 14:38:58 +00:00
.claude-plugin fix(plugin): add explicit hooks path to manifest 2026-02-28 09:28:02 +00:00
.devcontainer chore(devcontainer): remove invalid --no-version-check from tea login 2026-04-27 11:53:31 +00:00
bin feat: restructure as Claude Code plugin 2026-02-27 17:54:47 +00:00
defaults fix: LLM robustness, PostToolUse detection, deploy docs 2026-04-20 19:59:41 +00:00
devwork chore(inbox): clear resolved 10-report-html out-of-scope items 2026-04-27 11:59:24 +00:00
hooks feat(hooks): move LLM to PreToolUse + auto-promote GREEN decisions 2026-03-02 14:38:58 +00:00
src fix(13-report-html-path): default report path to ~/Documents/ 2026-04-27 12:34:20 +00:00
.gitignore feat(devcontainer): install tea CLI and /workspace/main layout 2026-04-20 19:59:27 +00:00
Cargo.lock feat: implement full permission hook binary with command chain parsing 2026-02-26 17:25:15 +00:00
Cargo.toml feat: implement full permission hook binary with command chain parsing 2026-02-26 17:25:15 +00:00
CLAUDE.md fix(13-report-html-path): default report path to ~/Documents/ 2026-04-27 12:34:20 +00:00
POST-MORTEM.md docs(archive): mark project laid to rest 2026-04-29 2026-04-29 15:08:41 +02:00
README.md docs(archive): mark project laid to rest 2026-04-29 2026-04-29 15:08:41 +02:00


⚠️ 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 customize
  • policy.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. For Bash, that's command. For Read/Write/Edit, that's file_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