Manage detect-secrets
Baseline mechanics for the detect-secrets pre-commit hook. The CLI is easy
to get wrong; use exactly these commands.
Command reference
There is no --update flag. The verbs are:
| Task | Command |
|---|---|
| Create baseline | detect-secrets scan > .secrets.baseline |
| Update baseline in place | detect-secrets scan --baseline .secrets.baseline |
| Review findings interactively | detect-secrets audit .secrets.baseline |
| One-off scan of a file | detect-secrets scan <path> |
scan --baseline rewrites the baseline file in place: new candidates are
added, resolved ones removed, line numbers refreshed.
Breaking the commit loop
Symptom: every commit fails with “The baseline file was updated … Please
git add .secrets.baseline”, and adding it just fails again on the next
commit.
The loop exists because the hook rewrites the baseline during the commit, so the staged copy is always one generation behind. Break it in one shot:
detect-secrets scan --baseline .secrets.baseline
git add .secrets.baseline
git commit
Run the scan yourself first, stage the result, then commit; the hook now
sees a baseline identical to the one it regenerates and passes. If it still
loops, the hook args in .pre-commit-config.yaml differ from your manual
invocation (compare exclude patterns and plugin flags; they must match, or
each side keeps rewriting the other’s output).
Line-number churn alone can also dirty the baseline on unrelated commits. That is normal; stage the refreshed baseline with the commit that moved the lines.
False positives
Prefer inline allowlisting over baseline hand-editing:
API_EXAMPLE = "sk-not-a-real-key" # pragma: allowlist secret
For whole paths (fixtures, lockfiles), add an exclude to the hook config:
- repo: https://github.com/Yelp/detect-secrets
rev: v1.5.0
hooks:
- id: detect-secrets
args: ["--baseline", ".secrets.baseline"]
exclude: package-lock.json|tests/fixtures/
After adding an exclude, regenerate the baseline (the update command above) so stale entries under the excluded path drop out.
Real findings
If audit marks a finding as a true secret: rotate the credential first,
remove it from the code (move to 1Password via manage-secrets), then scrub
history only if the secret ever reached a remote (git filter-repo), and
regenerate the baseline last.
Do not
- Do not delete the hook to unblock a commit; fix the baseline instead. If the team decides to drop detect-secrets, remove the hook, the baseline file, and the CI check together in one commit.
- Do not hand-edit JSON entries in
.secrets.baselinewhen a regenerate or an inline pragma does the job. - Do not commit a baseline generated with different exclude flags than the hook uses.