CoursesSecrets management foundationsDetecting secrets before merge

Detecting secrets before merge

gitleaks, pre-commit, and CI gates that stick.

In short. Secret scanning is the seatbelt you wear before the crash.

Beginner25 min · lesson 8 of 13

Secret scanning is the seatbelt you wear before the crash. Tools like gitleaks, trufflehog, and GitHub secret scanning look for known prefixes and high-entropy strings in commits, PRs, and sometimes full history. They will not catch every custom token format — but they catch the boring disasters that still dominate incident stats.

Scanning without a gate is a report nobody reads. Put scanners in pre-commit for fast feedback and in CI as a merge blocker. Baseline existing findings carefully; do not "skip all" forever. When a hit is real, rotate first, then clean history.

Pre-commit and CI

terminal
# install & run gitleaks against the repo
gitleaks detect --source . --verbose --no-git 2>/dev/null | head -20
# or:
gitleaks protect --staged
output
Finding: generic-api-key
Secret: ghp_...
File: scripts/old.sh
Line: 12
# FAIL (expected) — scanner found a token-shaped string

Generate a config that allows documented test fixtures (fake keys with obvious EXAMPLE markers) while blocking real formats. Educate developers: bypassing the hook to "just push" is an incident waiting to happen.

Detection loop
1Pre-commit
fast local catch
2CI gate
block merge on hits
3History scan
periodic full repo
4Rotate+purge
on confirmed leak
Org-wide scanning on the VCS platform catches pushes that skipped local hooks.
Allowlists grow like weeds
Every allowlist entry needs an owner and a reason. Review quarterly or you will allowlist a live production key "temporarily."

Going deeper

Entropy detectors catch custom tokens without known prefixes but raise false positives on certificates and random IDs. Tune rulesets per language monorepo; keep a documented allowlist of fixture files with EXAMPLE in the value.

Enable native VCS scanning (GitHub Advanced Security, GitLab secret detection) in addition to gitleaks so pushes that skip hooks still get caught. Configure push protection where the platform offers it.

Metrics: count secrets blocked per week, mean time to rotate after a true positive, and allowlist size. If allowlists only grow, your program is decaying.

Full-history scans on large monorepos are slow — run them nightly and on release tags while PR scans cover the diff plus a shallow window. Do not skip history entirely; old keys still work until rotated.

When scanners disagree, believe the hit until proven false. A single tool miss is common; two independent tools missing the same live key is rare. Prefer fail-closed on known prefixes even if entropy rules are warn-only.

Train developers with a deliberate "leaked fake key" exercise in onboarding so they see the CI gate fail safely. Fear without practice produces hook bypasses; practice produces respect for the control.

Try this

Commit a clearly fake ghp_exampleExampleExampleExample0001 in a branch, run gitleaks, confirm detection, then remove it.

terminal
echo 'token=ghp_exampleExampleExampleExample0001' > /tmp/leak-test.txt
gitleaks detect --source /tmp --no-git || true
output
Finding: github-pat
File: /tmp/leak-test.txt
# SUCCESS — detector fires on PAT shape

Takeaway

Scan early, gate merges, rotate on real hits, and keep allowlists honest. Scanning is necessary hygiene, not a substitute for a secrets manager.

Next: SOPS and sealed-secrets — encrypting values so GitOps can still store them.

Quick check
01A secret scanner CI gate should…
Incorrect — Warnings without gates are ignored.
Correct —
Incorrect — Use both layers.
Incorrect — Use obvious fakes in fixtures, not live keys.
02After gitleaks finds a live key in history…
Incorrect — Private is not enough.
Correct —
Incorrect — Insufficient.
Incorrect — No.

Related