Add PreToolUse guard hooks: generated-file + rbw vault pre-flight
Two project hooks (deny-only, fail open): block Write/Edit of generated inventories/<env>/hosts.yml, and block git commit when the rbw vault agent is locked. Both pipe-tested across all paths. Activate with a Claude Code restart (the watcher only tracks settings.json present at session start). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
11af84938d
commit
80bf9afea9
3 changed files with 89 additions and 0 deletions
25
.claude/hooks/guard-generated-files.sh
Executable file
25
.claude/hooks/guard-generated-files.sh
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# PreToolUse guard (Write|Edit): block edits to generated inventory files.
|
||||
# `inventories/<env>/hosts.yml` is produced by tf_to_inventory.py — editing it by
|
||||
# hand is overwritten on the next `make tf-inventory`. The git pre-commit hooks do
|
||||
# NOT catch this, so we enforce it here.
|
||||
#
|
||||
# Fails OPEN: any parsing/other error allows the action (never wedge tool use).
|
||||
#
|
||||
set -uo pipefail
|
||||
|
||||
input=$(cat 2>/dev/null) || exit 0
|
||||
file=$(printf '%s' "$input" | jq -r '.tool_input.file_path // empty' 2>/dev/null) || exit 0
|
||||
[ -n "$file" ] || exit 0
|
||||
|
||||
case "$file" in
|
||||
*/inventories/*/hosts.yml | inventories/*/hosts.yml)
|
||||
cat <<'JSON'
|
||||
{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"inventories/<env>/hosts.yml is GENERATED by tf_to_inventory.py. Edit terraform/environments/<env>/main.tf (local.vms) and run `make tf-inventory`. The control node is the documented manual exception (docs/runbooks/new-host.md)."}}
|
||||
JSON
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
35
.claude/hooks/guard-vault-preflight.sh
Executable file
35
.claude/hooks/guard-vault-preflight.sh
Executable file
|
|
@ -0,0 +1,35 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# PreToolUse guard (Bash): block `git commit` when the rbw vault agent is locked.
|
||||
# The pre-commit ansible-lint hook decrypts vault.yml via rbw, so a commit while
|
||||
# locked fails deep with a confusing error. This catches it early with a clear fix.
|
||||
#
|
||||
# Fails OPEN: only blocks on a definitive "rbw present AND not unlocked" signal.
|
||||
# If rbw is missing, the command isn't a plain `git commit`, or `--no-verify` is
|
||||
# used, the action is allowed.
|
||||
#
|
||||
set -uo pipefail
|
||||
|
||||
input=$(cat 2>/dev/null) || exit 0
|
||||
cmd=$(printf '%s' "$input" | jq -r '.tool_input.command // empty' 2>/dev/null) || exit 0
|
||||
|
||||
case "$cmd" in
|
||||
*"git commit"*) : ;; # a git commit — check further
|
||||
*) exit 0 ;; # not a commit — allow
|
||||
esac
|
||||
case "$cmd" in
|
||||
*"--no-verify"*) exit 0 ;; # hooks skipped anyway — allow
|
||||
esac
|
||||
|
||||
command -v rbw >/dev/null 2>&1 || exit 0 # rbw not installed — allow
|
||||
|
||||
if rbw unlocked >/dev/null 2>&1; then
|
||||
exit 0 # unlocked — allow
|
||||
fi
|
||||
|
||||
# rbw present but not unlocked (locked or agent not running) — the commit would
|
||||
# fail in the pre-commit hook, so block early with guidance.
|
||||
cat <<'JSON'
|
||||
{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"rbw is locked — the pre-commit ansible-lint hook needs the vault password to decrypt vault.yml. Run: rbw unlock"}}
|
||||
JSON
|
||||
exit 0
|
||||
29
.claude/settings.json
Normal file
29
.claude/settings.json
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/claude-code-settings.json",
|
||||
"hooks": {
|
||||
"PreToolUse": [
|
||||
{
|
||||
"matcher": "Write|Edit",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "bash \"${CLAUDE_PROJECT_DIR:-.}/.claude/hooks/guard-generated-files.sh\"",
|
||||
"timeout": 10,
|
||||
"statusMessage": "Checking generated-file guard"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": "Bash",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "bash \"${CLAUDE_PROJECT_DIR:-.}/.claude/hooks/guard-vault-preflight.sh\"",
|
||||
"timeout": 10,
|
||||
"statusMessage": "Checking rbw vault pre-flight"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue