Stdlib-only safety hooks for Claude Code.
$ rm -rf /
guard: deny - rm -rf against /, /*, ~, $HOME, ., or ./ is catastrophic.
Guardrails not walls: guard catches the obvious foot-guns at the Claude Code hook layer so a stray tool call doesn't turn into a bad day. It is defense-in-depth, not a security boundary.
| Hook | What it catches |
|---|---|
| bash_command_validator | dangerous shell commands (rm -rf, eval/source, env-var hijack, shell-wrapper bypass) |
| git_c_validator | git -C path traversal, git -c key=value config injection, git commit -C silent message reuse |
| credential_check | hardcoded credentials in tool inputs |
| commit_message_validator | malformed/missing commit messages |
| agent_output_guard | oversized raw-data reads in subagent output |
| protected_files | edits to user-marked protected files |
| subagent_scope | subagent edits outside declared scope |
/plugin marketplace add tracinehq/guard
/plugin install guard@tracinehq
tracinehq/guard is the GitHub owner/repo shorthand for the marketplace source. guard@tracinehq is the <plugin>@<marketplace> reference Claude Code uses to install. To pin a specific tag:
/plugin marketplace add tracinehq/guard#v1.0.0
- Claude Code v2.0.0+ (plugins entered public beta on 2025-10-09)
- Python 3.11+ available on
python3PATH (no third-party dependencies) - POSIX shell environment (Linux, macOS, WSL). Windows is not supported in v1 — the matchers target POSIX shell shapes (
rm -rf,cat ~/.aws/credentials, process substitution) and offer no meaningful protection against PowerShell orcmd.exeequivalents. CI runs onubuntu-latestandmacos-latest.
Guard reads a small set of environment variables. See SKILL.md for the canonical descriptions and defaults.
| Variable | Purpose |
|---|---|
CLAUDE_AUTONOMOUS |
Strict default-deny in subagents / driven runs |
GUARD_DECISIONS_PATH |
Override the JSONL decision-log path |
GUARD_AUTONOMOUS_QUEUE_PATH |
Override the autonomous-deny queue path |
GUARD_DEBUG |
Emit per-hook debug to stderr |
GUARD_DATA_DIR |
Override guard's data directory |
To disable an individual hook, remove its entry from ~/.claude/settings.json PreToolUse, or comment the line in hooks/hooks.json if you forked the plugin.
- Not a security boundary. A determined attacker who controls input to Claude Code can bypass any client-side hook.
- Defense-in-depth, not an exclusive safety mechanism.
- Logs decisions for observability; doesn't enforce server-side.
Every decision is appended to ~/.claude/guard-decisions.jsonl (NDJSON, one record per line). The schema is stable and documented in docs/JSONL_FORMAT.md.
Tail and pretty-print:
tail -f ~/.claude/guard-decisions.jsonl | jq
Or use the built-in guard CLI for read-side queries:
guard status # installation status + log location + line count
guard noisy --since 7d # top hit rules in the last week
guard silent --since 30d # rules that haven't fired in 30 days
guard trace <session-id> # all records for a single session
guard test "<command>" # what would each hook decide?
guard diff # effective merged config (stub)
just check
Runs lint, typecheck, and tests. See CONTRIBUTING.md for setup, test tiers, and commit conventions.
Guard is defense-in-depth, not a security boundary. The validators trade exhaustive coverage for low false-positive rates and stdlib-only portability, which means a determined attacker who controls Claude Code's input can bypass any client-side hook. Pattern-matching is conservative on purpose: rules deny shapes that have a clear safer alternative and pass shapes that are ambiguous. For the threat model, the disclosure process, and a list of areas guard explicitly does not cover, see SECURITY.md.
Apache 2.0 — see LICENSE.