Caulking installs global Git hooks that run gitleaks so you don’t accidentally commit or push secrets.
It’s intentionally boring:
- deterministic install
- predictable XDG layout
- explicit verify/audit
- minimal moving parts
If you want fancy, you’re in the wrong repo. If you want “it works the same every time,” welcome.
After install, Git will use a global hooks directory:
- Hooks live at:
~/.config/git/hooks/pre-commit(scans staged changes)pre-push(scans the pushed range)
- Git is set to use it globally:
git config --global core.hooksPath ~/.config/git/hooks
Caulking also writes a global gitleaks config:
~/.config/gitleaks/config.toml
Important: the global config must extend defaults, or you’ve built security theater:
[extend]
useDefault = trueRequired:
gitbashgitleaksv8+ (Caulking will try to install/upgrade via Homebrew on macOS)
Optional (but useful):
brew(macOS install helper)prekorpre-commit(only needed if you want to run repo lint/format hooks viamake lint)
git clone <repo-url>
cd caulking
make install
make verifyIf make verify fails, it will tell you what is broken and how to fix it. The output is not lyrical, but it is correct.
Once installed, you don’t “run” Caulking.
You just work:
git commit -m "..."
git pushIf you stage or push something that looks like a secret, gitleaks blocks it. That is the whole point.
False positives happen. The correct fix is to teach the scanner, not to train yourself to ignore warnings.
Add a file named .gitleaks.repo.toml at the root of your repository:
title = "Repo allowlist"
[extend]
useDefault = true
[allowlist]
description = "Allow known-safe patterns for this repo"
regexes = [
# Example: fake test secret used in fixtures
"FAKE_TEST_SECRET_12345",
]
paths = [
# Example: allow generated artifacts or fixtures
"fixtures/.*",
]This is the right default for:
- test fixtures
- fake credentials
- intentionally embedded example tokens
- generated files you do not control
It keeps the global policy strict while allowing local exceptions where they make sense.
The global gitleaks config lives at:
~/.config/gitleaks/config.toml
It contains a small allowlist section:
[allowlist]
regexes = [
"(?i)example(_|-)?key",
"(?i)dummy(_|-)?secret",
]Only put patterns here that are:
- universally safe across all repos you work in
- genuinely non-secret examples
If you find yourself wanting to add lots of entries here, you are probably doing the wrong thing. Move them into a per-repo allowlist instead.
If you need to bypass gitleaks for a single operation:
SKIP=gitleaks git commit -m "..."
SKIP=gitleaks git pushThis is an escape hatch, not a workflow. If you use it often, your rules are wrong and you should fix them.
This repo includes a local .pre-commit-config.yaml for formatting and linting itself.
make lintUses:
prekif available- otherwise
pre-commit
If neither is installed, it fails loudly. This is deliberate.
Verify proves that enforcement actually works:
make verifyAudit is intentionally boring and currently aliases verify:
make auditIf you want pretty dashboards, write one. This tool is about not leaking secrets.
Hooks:
~/.config/git/hooks/pre-commit~/.config/git/hooks/pre-push
Gitleaks config:
~/.config/gitleaks/config.toml
State:
~/.config/caulking/previous_hookspath
This exists solely to restore your previous core.hooksPath on uninstall. It is not a feature. It is housekeeping.
git config --global --get core.hooksPath
ls -la ~/.config/git/hooksIf that path is wrong or the files aren’t executable, your hooks won’t run. This is not subtle.
chmod +x install.sh uninstall.sh verify.sh hooks/*.sh scripts/*.sh tests/*.shThen rerun:
make installIf a repo sets a local core.hooksPath, it can override the global one.
Check a tree of repos with:
./check_repos.sh <root_dir> check_hooks_pathFix the offenders. Don’t normalize bypassing guardrails.
make uninstallThis:
- removes installed hook scripts
- restores your previous
core.hooksPathif recorded - leaves your global gitleaks config in place (on purpose)
If you want to fully nuke state, you can remove the XDG directories yourself. That is your call.
Do not report security issues in public GitHub issues.
Follow SECURITY.md and cloud.gov’s security.txt.
This project is public domain (CC0). See LICENSE.md.