Kay van Dijk
Once was enough
The README says it in one line: built after leaking a key once. Once was enough. I am not going to dress that up. A secret got into a place it should not have been, and I wrote a small check so the boring mistakes stop at the commit.
dotenv-guard does two jobs. It blocks committing .env files, and it flags a short list of secret patterns in what you are about to record. It is a CLI and a pre-commit hook. It is not a full secret scanner, and the README says that on purpose. A short list I understand is more useful to me than a huge one I have not read.
Scan, or only what is staged
dotenv-guard and dotenv-guard scan walk a directory. You can pass paths: dotenv-guard scan app config. dotenv-guard check-staged looks at the git index, the files the next commit will record. A file you have not git added is ignored by the hook. Use scan when you want the working tree. A clean run prints ok and exits 0. A hit exits 1 and prints one line per finding, like .env.local: env file, or app/settings.py:18: AWS access key.
.env.example and .env.sample are allowed. .env, .env.local, .env.production, and any other .env.* are not. Case does not matter, so .ENV is blocked too. I have seen that one.
The patterns
It looks for AWS access key ids that start with AKIA, and aws_secret_access_key assignments. Stripe live keys, sk_live_ and rk_live_. PEM private keys. GitHub tokens: ghp_, gho_, ghu_, ghs_, ghr_, and github_pat_. WooCommerce consumer keys and secrets, ck_ and cs_. Slack tokens, Google API keys, npm tokens. That is the list. If your secret does not look like one of those, this tool will not catch it. I would rather you know that than trust a green "ok" as a security audit.
Directory walks skip .git, node_modules, virtualenvs, and build folders. Only the first 1 MB of a file is scanned. A null byte in that chunk means the file is treated as binary and left alone. I do not want it to spend an evening reading a video, or to flag random bytes inside one.
The hook
The repo includes .pre-commit-hooks.yaml. From another project you point pre-commit at github.com/kaygaaf/dotenv-guard, pin a rev that exists, and use the hook id dotenv-guard. The hook runs dotenv-guard check-staged. The README example uses rev v0.1.0. Pin whatever tag you actually have. Do not leave a floating branch in there and call it done.
If you installed the command yourself and want the local binary, the README has a repo: local hook. entry is dotenv-guard check-staged, language system, pass_filenames false, always_run true. pass_filenames false because the command reads the index itself. It does not want pre-commit to hand it a subset of paths and then miss a staged .env that was not in that subset.
Install from a checkout is pip install -e . which puts dotenv-guard on your PATH. python -m dotenv_guard works too. Tests are python -m unittest.
I still read diffs. This only catches the class of mistake I already made: an env file in the commit, or a token that looks like the ones on the list. It will not stop me from pasting a password into a comment in some creative format. That is fine. The tool is there so the obvious one does not happen twice.
