Conversation
Deny-capable guards previously ran only on PreToolUse(Bash). File writes through Write/Edit/MultiEdit were seen only by an advisory PostToolUse hook, after the write. An agent could create the disable file, overwrite a privileged path, write to auto-executed files (git hooks, shell rc), or write live secrets to disk without any blocking guard inspecting it. New PreToolUse pre-edit dispatcher (Write|Edit|MultiEdit, deny-capable) plus edit_path_guard and edit_secret_guard. install.sh registers the hook. SECURITY.md documents the coverage. 17-case pre-edit suite (secret fixtures assembled at runtime, no literals); adversarial (49) and regression (95) pass. Reported by a reader (ANP2) on our Dev.to article. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ufhc1yA1eXGSjUKE5QGSdF
# Conflicts: # package.json
Cross-review of 0.4.0 found a hole: edit_path_guard protected guards/core and guards/pro, but the pre-edit dispatcher also auto-sources custom guards. An agent could Write a custom guard (uncovered), which would be sourced and executed on the next tool call, bypassing the whole system. Now covers guards/custom, dispatchers, and lib. Three regression tests added. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ufhc1yA1eXGSjUKE5QGSdF
…s (v0.4.2)
Two gaps found by the full test sweep:
- credential_leak_guard: sk-ant-[A-Za-z0-9]{20,} stopped at the first hyphen,
so real keys (sk-ant-api03-...) were NOT detected. Now allows [-_] in the body.
- self_correction_loop: missed standalone "error TS####" output that has no
literal "tsc" nearby. Added error TS[0-9]{3,} to the build-error pattern.
new-guards suite now 43/43 (was 41/2). adversarial 49, regression 95,
pre-edit 20 all green.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ufhc1yA1eXGSjUKE5QGSdF
Cross-review found the highest-value bypass still open: an agent could Write ~/.claude/settings.json (the hook registry install.sh writes) and remove the PreToolUse entries, disabling pre-bash AND pre-edit (including this guard) without touching any 'guardrail' path. edit_path_guard now blocks file-tool writes to .claude/settings(.local).json. Two regression tests added. pre-edit 22/22, adversarial 49, regression 95, new-guards 43 all green. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ufhc1yA1eXGSjUKE5QGSdF
Cross-review follow-up: _guardrail_run silently skipped a missing guard function, so a future change that dropped hook_edit_path_guard would fail open to allow. Now mirrors pre-bash: a missing or failing required guard denies with an integrity error. Part of v0.4.3. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ufhc1yA1eXGSjUKE5QGSdF
Cross-review mediums: - edit_path_guard logged "warned" then denied the git-hook/startup case; now logs "blocked" to keep the audit trail truthful. - NotebookEdit is a file-write tool but was outside the matcher, while SECURITY.md claimed full file-write coverage. Added NotebookEdit to the install matcher; dispatcher now reads notebook_path + new_source. 3 NotebookEdit regression tests (secret, settings.json, benign). pre-edit 25/25, adversarial 49, regression 95, new-guards 43 all green. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ufhc1yA1eXGSjUKE5QGSdF
Cross-review: the dispatcher auto-sources preedit_*.sh from $GUARDRAIL_CUSTOM_GUARDS_DIR, but the guard only matched the hardcoded guards/custom path. A write into an operator-configured custom dir was the same bypass. Guard now also blocks writes under the configured dir when set. Every auto-sourced path is now covered. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ufhc1yA1eXGSjUKE5QGSdF
Load guardrail-common early so the payload-validation deny is logged, not just blocked. Malformed-input probing is now visible in the audit trail. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ufhc1yA1eXGSjUKE5QGSdF
Cross-review KRITISCH: path checks matched $FILE_PATH literally, so /a/./settings.json, /a//settings.json and /a/../a/settings.json wrote to a protected file but slipped past the regex. Guard now canonicalizes with realpath -m -s (normalizes ./ ../ // without resolving symlinks) before matching. Three normalization-bypass regression tests added. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ufhc1yA1eXGSjUKE5QGSdF
…ads (v0.4.3) Cross-review HOCH: a non-string content/new_string/new_source made jq error, CONTENT went empty, and edit_secret_guard returned early, passing secrets unscanned. Extraction now coerces non-string values to JSON (so embedded secrets are still scanned) and denies if jq itself errors. Regression test with an object-typed content carrying a key added. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ufhc1yA1eXGSjUKE5QGSdF
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ufhc1yA1eXGSjUKE5QGSdF
…ction) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ufhc1yA1eXGSjUKE5QGSdF
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Syncs develop into main. Published to npm across 0.4.0-0.4.3.
What changed
GuardRail enforced on Bash only; file writes via Write/Edit/MultiEdit/NotebookEdit
bypassed all deny-capable guards. This adds a deny-capable PreToolUse pre-edit
dispatcher and closes every bypass a 10-round adversarial cross-review surfaced.
Coverage now
GUARDRAIL_CUSTOM_GUARDS_DIR, .claude/settings(.local).json, privileged
paths, git hooks / shell rc
Verification
pre-edit 29/29, adversarial 49/49, regression 95/95, new-guards 43/43,
installer 3/3, typecheck clean. 10 cross-review rounds, final round clean.
🤖 Generated with Claude Code