Add block-secret-files hook - #1
Merged
Merged
Conversation
PreToolUse hook that denies Read, Edit, Write and NotebookEdit calls targeting files that look like secrets: .env and variants, private keys, keystores, credential stores, and anything inside .ssh/, .gnupg/ or .aws/. Example and template files are allowed on purpose, since those are what Claude should be reading anyway. It returns a permissionDecision of "deny" with a reason, so Claude can act on it by asking for the one value it needs instead of reading the whole file. It fails open: an unreadable payload or a tool without a path is allowed through, because a broken guardrail should not break the session. Known limits, documented in the hook's README: it does not match Bash, so `cat .env` still works, and it does not scan file contents. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adds the metadata the plugin schema supports: $schema for editor autocomplete, keywords, license, homepage and repository. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
KainDitmer
requested changes
Aug 13, 2026
KainDitmer
left a comment
Contributor
There was a problem hiding this comment.
This branch has conflicts that must be resolved
Use the web editor or the command line to resolve conflicts before continuing.
.claude-plugin/marketplace.json
README.md
main now carries git-guardrails and project-checks; both sides appended to marketplace.json and the README hooks table, so all three entries are kept in alphabetical order. Switched the hook to the exec form CONTRIBUTING requires. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
PR #4 landed on main while this branch was being updated, adding one more marketplace entry and README row in the same two spots. All four hooks kept, alphabetical. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Adds the first hook to the repo: a
PreToolUseguardrail that stops Claude from reading or writing files that look like secrets.Why
Claude reads whatever a task seems to need, and "seems to need" regularly includes
.env. Nothing in Claude Code stops that by default. Permission rules can, but they are per-project and easy to forget on the project where it matters. A hook applies everywhere, once.The point is not that a leaked
.envis catastrophic on its own — it is that the contents end up in a transcript, and transcripts get shared, summarised and stored.What it does
Denies
Read,Edit,WriteandNotebookEditwhen the target path matches a secret pattern:.envand its variants,*.pem,*.key,*.p12,*.pfx, keystores,id_rsaand friends,*.kdbx,credentials,service-account*.json,.npmrc,.pypirc,.netrc,.htpasswd, plus anything inside.ssh/,.gnupg/,.aws/and the.docker/config.json/.kube/configfiles.*.example,*.sample,*.template,*.distand the.env.examplefamily are allowed on purpose. Those are the files Claude should be reading.It returns a
permissionDecisionofdenywith a reason, so Claude gets told why and can ask for the single value it needs instead of giving up or retrying.What it deliberately does not do
Bash.cat .envstill works. Blocking that reliably needs command parsing, not path matching, and the false-positive rate is not worth it. Stated plainly in the hook's README rather than left for someone to discover.config.phpgoes through.Seatbelt, not vault.
Testing
./scripts/validate.shpasses.The script was exercised directly with ten payloads:
.env.env.local.env.exampleenv.example~/.ssh/id_ed25519~/.kube/confignotebook_path=.envsrc/app.ts{}Reproduce with the two commands in the hook's README.
Review notes
This is shell that runs automatically on every matching file operation, so it is worth reading the script rather than trusting the description. It is 129 lines of dependency-free Python: three pattern lists at the top, one
fnmatchcheck, no network, no writes, no reads beyond stdin.🤖 Generated with Claude Code