Files
security-hooks/README.md
Flo 7645402347 Replace bash shim with Rust binary
Bash shim had shell quoting risks and depended on socat/nc. Elixir
escript would pay ~300ms BEAM boot per invocation. A second Burrito
binary would unpack on every cold call. Rust gives <1ms startup,
proper timeout handling, and is already in the toolchain for the
tree-sitter NIF.

- Add shim/ Rust crate to directory structure
- Document Rust shim rationale (vs bash, escript, Burrito)
- Update Dependencies with shim crate deps (serde_json, stdlib Unix socket)
- Update install script, README, architecture diagram

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 12:28:18 +02:00

4.0 KiB

security-hooks

Defense-in-depth security hooks for AI coding agents. Works with Claude Code, Gemini CLI, and Codex.

A single daemon evaluates every tool call against configurable rules — blocking destructive commands, catching data exfiltration, and flagging suspicious behavior before it reaches your system.

How it works

AI Agent ──► Rust Shim ──► Unix Socket ──► Elixir Daemon ──► Verdict
              (<1ms)         (<1ms)        (rule engine)     allow/deny/ask
  1. The AI tool calls a hook before each tool use (bash command, file edit, MCP call)
  2. A tiny Rust binary forwards the payload to a long-running Elixir daemon
  3. The daemon evaluates rules using two layers:
    • Regex — fast pattern matching for obvious threats (fork bombs, miners)
    • AST — structural analysis via tree-sitter-bash that catches evasion (rm -rf $(echo /), piped exfiltration, obfuscated commands)
  4. Returns allow, deny (with a nudge message), or ask (falls through to human approval)

The system is fail-closed — if the daemon is unreachable, the tool call is blocked.

Threat coverage

  • Prompt injection — malicious content in READMEs, web pages, or MCP responses can't trick the agent into running blocked commands
  • Destructive operationsrm -rf, force push, sudo, cloud resource deletion, and more
  • Data exfiltration — detects secrets being piped to curl/nc, reads of ~/.ssh or ~/.aws, env var leaks
  • Supply chain attacks — flags dependency mutations, unknown executables, lockfile edits
  • MCP injection — validates MCP server identity, scans parameters for shell injection via AST

Rule DSL

Rules live in .rules files with a custom syntax designed for regex without escaping pain:

# Regex — pattern is literal to end of line, no quoting needed
block "fork-bomb"
  match :\(\)\s*\{.*\|.*&\s*\}\s*;
  nudge "Fork bomb detected"

# AST — structural matching that catches evasion
block "destructive-rm"
  match command("rm") with_flags("-r", "-rf", "-fr")
  nudge "Use trash-cli or move to a temp directory"

block "pipe-to-exfil"
  match pipeline_to("curl", "wget", "nc")
  nudge "Don't pipe output to network commands"

# Config-referenced allowlist
suspicious "unknown-executable"
  match_base_command_not_in allowed_executables
  nudge "Unknown command '{base_command}'. Add it to config.toml"

The rule loader auto-detects regex vs AST based on whether the match starts with a function like command(.

Two tiers

  • block — hard deny. The agent sees the nudge and self-corrects.
  • suspicious — falls through to the human permission prompt with context.

Configuration

# config.toml — defaults ship with the project
[executables]
allowed = ["git", "mix", "cargo", "go", "node", "npm", "python", "rg", "fd", ...]

[secrets]
env_vars = ["AWS_SECRET_ACCESS_KEY", "GITHUB_TOKEN", "DATABASE_URL", ...]

[paths]
sensitive = ["~/.ssh", "~/.aws/credentials", "~/.config/gcloud", ...]

Override with config.local.toml (gitignored):

[executables]
append = ["my-custom-tool", "deno"]
exclude = ["curl"]

[rules]
disabled = ["force-push"]

Architecture

  • Rust shim — ~1MB static binary, <1ms startup, forwards payloads via Unix socket
  • Elixir daemon — distributed as a Burrito binary (no Erlang/Elixir install needed)
  • Adapter layer — normalizes payloads across Claude Code, Gemini CLI, and Codex
  • tree-sitter-bash — Rust NIF for robust AST parsing of shell commands
  • Hot-reload — edit rules or config, changes apply on the next tool call
  • systemd/launchd — socket activation for zero cold-start latency, automatic crash recovery

Platforms

macOS (aarch64, x86_64) · Linux (x86_64, aarch64) · WSL

Status

Design phase. See docs/superpowers/specs/2026-03-26-security-hooks-design.md for the full spec.

License

TBD