Skip to content

Safety Hooks

claude-ops bot edited this page Apr 26, 2026 · 1 revision

Safety Hooks

v2.0 — Three universal PreToolUse:Bash hooks that block the most common foot-guns.

Repo deep-dive: docs/safety-hooks.md.

Why these are not gated by userConfig

Other v2 subsystems are toggleable from /plugins settings because they're convenience layers. The three safety hooks prevent irrecoverable damage (committed secrets, deleted home directories, broken main branches). They're always-on by design, with a per-incident escape via Claude Code's standard permissionDecision flow.

If you genuinely need to disable one, comment out the entry in hooks/hooks.json.

The three hooks

bin/ops-prevent-secret-commit

Trigger: PreToolUse:Bash matching git commit *.

Action: Scans git diff --cached for secret patterns. On match, returns permissionDecision: deny.

Patterns: AWS access/secret keys, GitHub PATs (ghp_, github_pat_), Slack tokens (xoxb-/xoxp-/xoxa-), OpenAI (sk-/sk-proj-), Anthropic (sk-ant-), Stripe live (sk_live_), staged .env* files (excluding .env.example/.env.template), and high-entropy strings near KEY/TOKEN/SECRET variable names.

bin/ops-no-rm-rf-anchor

Trigger: PreToolUse:Bash matching rm -rf * (and -fr, -rfv).

Action: Resolves each target via realpath/readlink -f. On any of these resolved targets, returns permissionDecision: deny:

  • /
  • $HOME / ~ (and any path that resolves to $HOME)
  • .. and . (when CWD itself is $HOME or /)
  • Mount points listed in /etc/fstab (root-level only)

bin/ops-warn-mainpush

Trigger: PreToolUse:Bash matching git push *.

Action: Reads the current branch. If it's in the protected list (main, master, prod, production, release), returns permissionDecision: ask. Force-push to main is sometimes legitimate (hotfix, recovery) — but it should never be silent.

Disabling a single hook

Edit hooks/hooks.json and remove the entry under PreToolUse > Bash. Reload (/plugin reload ops).

Testing

tests/test-safety-hooks.sh covers every hook with positive (should-deny / should-ask) and negative (should-allow) cases. 45/45 pass on macOS + Linux.

See also

Clone this wiki locally