Skip to content

date: 2026-06-11 tags: [security, gitleaks, ci, github-actions, secret-scanning] status: active graduated_to:

Gitleaks footgun pair: a custom config drops every default rule, and the action needs a license on org repos

Symptom — the #307 security gate as first built would have (a) failed every PR: gitleaks/gitleaks-action@v2 requires a GITLEAKS_LICENSE for organization-owned repos (Tomat-Labs is an org; the agent's comment claimed the empty license merely disabled SARIF upload — wrong), and (b) had it run, detected nothing: a .gitleaks.toml containing only an [allowlist] block replaces the built-in ruleset, so the scan runs with zero rules and reports clean on everything.

Root cause — two quiet defaults. The action gates org usage behind a license key even for the plain exit-code use; and gitleaks treats any custom config as the whole config unless it opts back in with [extend] useDefault = true. Both failure modes are silent-ish: one is loud in the wrong way (every PR red), the other is the worst kind of green.

Fix — invoke the pinned gitleaks binary directly in the workflow (gitleaks dir . --config .gitleaks.toml, version-pinned download — no license needed) and add [extend] useDefault = true to .gitleaks.toml (.github/workflows/security.yml, PR #402, commit 4ab5071).

Guard — canary-test any secret-scan config in both directions before trusting it: the real tree must pass, and a planted fake secret (sk_live_… in a scratch dir) must fail with exit 1. A secret scanner proven only on a clean tree is unproven.