Repository navigation
gitleaks binary is pinned to 8.21.2 (Oct 2024) with no update path — Renovate cannot see it, and the anthropic-api-key rule does not exist in it #30
Description
The reusable secret-scanning workflow pins the gitleaks binary as a bare string with no update path:
$ gh api repos/FlowMatrix-AI/.github/contents/.github/workflows/gitleaks.yml --jq .content | base64 -d
15: gitleaks-version:
16: description: gitleaks release version (no leading v)
17: type: string
18: default: "8.21.2"
...
34: v="${{ inputs.gitleaks-version }}"
35: curl -sSL "https://github.com/gitleaks/gitleaks/releases/download/v${v}/gitleaks_${v}_linux_x64.tar.gz" \
$ gh api repos/gitleaks/gitleaks/releases/tags/v8.21.2 --jq '"\(.tag_name) \(.published_at)"'
v8.21.2 2024-10-28T13:32:54Z
$ gh api repos/gitleaks/gitleaks/releases/latest --jq '"\(.tag_name) \(.published_at)"'
v8.30.1 2026-03-21T02:17:58Z
Every repo in the org scans with a scanner published 2024-10-28, and nothing will ever tell us.
Renovate cannot see it
It is a string interpolated into a curl URL, not a uses: ref. Renovate's own dashboard reports exactly one dependency in this file:
$ gh issue view 12 --repo FlowMatrix-AI/.github --json body --jq .body
<details><summary>.github/workflows/gitleaks.yml (1)</summary>
- `actions/checkout v7@3d3c42e5aac5ba805825da76410c181273ba90b1`
</details>
So the one line in this file that decides what a secret scan can detect is the one line no automation is watching.
Blast radius: every repo, and no caller overrides the default
$ for r in <each repo>; do gh api repos/FlowMatrix-AI/$r/contents/.github/workflows/secret-scan.yml ... ; done
site-omws-main gitleaks.yml@d2eab9f overrides gitleaks-version: 0
site-hillsandthrills-main gitleaks.yml@d2eab9f overrides gitleaks-version: 0
site-ruttedbuck-main gitleaks.yml@d2eab9f overrides gitleaks-version: 0
site-marketfourseasons-main gitleaks.yml@5eb6dcf overrides gitleaks-version: 0
site-thehuntadvisory-main gitleaks.yml@8aa9018 overrides gitleaks-version: 0
site-flowmatrixai-main gitleaks.yml@5eb6dcf overrides gitleaks-version: 0
site-flowmatrixai-studio gitleaks.yml@158c596 overrides gitleaks-version: 0
marketing-site-engine gitleaks.yml@d2eab9f overrides gitleaks-version: 0
Eight repos, four different pinned revisions of this workflow — and all four revisions carry default: "8.21.2", verified at each SHA. Renovate keeps the callers' workflow pins current, which is why this looks healthy from the caller side; bumping the pin has never changed the scanner.
What the gap actually costs — this is the part that matters
Not a version delta. The org config sets useDefault = true (this workflow's own comment: "useDefault = true in the org config chains through, so the built-in rules stay active either way"), so the binary's built-in ruleset is what does the detecting, and it is frozen at 8.21.2.
$ for t in v8.21.2 v8.30.1; do gh api "repos/gitleaks/gitleaks/contents/cmd/generate/config/rules?ref=$t" \
--jq '[.[] | select(.name|endswith(".go")) | select(.name|endswith("_test.go")|not)] | length'; done
119
131
Twelve rule files added, none removed:
anthropic.go artifactory.go clickhouse.go freemius.go looker.go maxmind.go
meraki.go notion.go perplexity.go settlemint.go sonar.go sourcegraph.go
anthropic.go is the one to read. It does not exist at v8.21.2 (404), and at v8.30.1 it is:
RuleID: "anthropic-api-key",
Regex: utils.GenerateUniqueTokenRegex(`sk-ant-api03-[a-zA-Z0-9_\-]{93}AA`, false),Every repo in this org is worked on with Claude Code. An sk-ant-api03-… key committed to any of them is not detected by the scanner we run, on any branch, on any scheduled sweep. The same holds for Notion and Perplexity tokens, and for Artifactory and Sonar credentials.
Fix
Bump default: to "8.30.1" and give the line an update path, so this cannot silently rot again. Options, cheapest first:
- A Renovate
customManagers(regex) rule matching thedefault:line in this file withdatasource=github-releases,depName=gitleaks/gitleaks. Keeps the existing shape and makes the version a tracked dependency. - Drop the pin and resolve the latest release at run time. Rejected as written — it makes the scan non-reproducible and puts an unreviewed binary in CI.
(1) is the one worth doing.
Found while triaging follow-ups from adversarial reviews on marketing-site-engine. The original review claim was "site-thehuntadvisory-main's gitleaks pin is 7 commits behind" — that was false on its premise: the site pins the workflow at a SHA while the template documents @main, so the caller is stricter, and the one intervening commit that touches this file is a no-op for it. Checking that claim is what surfaced the real one.
Related: #25 (the last detection-rule gap filed here).
Activity
CameronBrooks11 commentedon Sep 10, 2026
Verified, measured, and fixed in #31 (not merged).
What held up, and what did not
default: "8.21.2"at line 18maingitleaks-versionanthropic-api-keyruleThe undercount is the part worth correcting. The listing in the description covered eight repos; enumerating the whole org finds this workflow called by 66 of 67:
Nine distinct revisions of this file are pinned across them (
158c5963,1bbaee7d,5eb6dcf1,8aa90186,bbd63dc5,d12147b2,d2eab9f6,df3d01bf,fdd02918), spanning 2026-07-06 to 2026-09-05, anddefault: "8.21.2"is present at every one — checked at each SHA, not inferred.The rule gap, pinned down
anthropic.gofirst ships in v8.28.0 (2025-07-20). Absent at 8.21.2, 8.22.0, 8.23.0, 8.24.0, 8.25.0, 8.26.0, 8.27.0, 8.27.1, 8.27.2; present from 8.28.0 through 8.30.1. It definesanthropic-api-keyandanthropic-admin-api-key(sk-ant-admin01-…), which the description missed.The null result has a positive control: the same v8.21.2 listing does contain
openai.go, so the check would have foundanthropic.gohad it been there.Not argued from source — run against a throwaway repo holding one synthetic key of each shape, with this org's
.gitleaks.toml:Built-in rule IDs: 195 at v8.21.2, 222 at v8.30.1 (
grep -cE '^\s*id\s*=' config/gitleaks.tomlat each tag). Beyond Anthropic, the additions that matter here include both Amazon Bedrock key rules,perplexity-api-key,notion-api-token,1password-secret-key, two Sentry token rules,heroku-api-key-v2, two routable GitLab token rules, andsonar-api-token.Blast radius: zero
All 66 callers were cloned with full history and scanned with both versions, replicating what the workflow does (fetch the org config to
.gitleaks.org.toml, copy to.gitleaks.tomlonly where the repo has none, thengitleaks git --redact -v --config .gitleaks.toml).0 findings on 8.21.2. 0 findings on 8.30.1. No repo turns red, and no allowlist entries are needed — so no repo needs to fork the org config either. 145 MB and ~4,900 commits scanned.
Three checks behind that null result:
.gitleaks.tomlalso gain the coverage: injecting a synthetic key into one gives 1 finding on 8.21.2 and 2 on 8.30.1, becauseuseDefault = truechains the new built-ins through. No edits needed there.gitleaks gitdefaults to--all, so on the largest caller it scanned 412 commits whererev-list HEADis 364.No true positives. Nothing is being withheld from this thread.
Fix
#31 takes option (1) from the description.
default:moves to8.30.1and carries:Renovate's own
customManagers:githubActionsVersionspreset uses exactly this comment convention but its matchString only accepts a key ending in_VERSION, so a workflow inputdefault:never matches — hence a small customManager inrenovate.json, written by shape rather than naming gitleaks.extractVersionis load-bearing: the tag isv8.30.1and the curl URL supplies its ownv.Proven by running renovate itself against the branch (
--platform=local --dry-run=lookup, renovate 44.61.5): extraction goes from 4 files / 5 deps onmainto 6 files / 7 deps, with"depName": "gitleaks/gitleaks", "currentValue": "8.30.1", "datasource": "github-releases", "currentVersion": "8.30.1", "updates": []. It also concatenates with rather than replacing the org preset'suv tool installmanager — verified againstmergeChildConfig, which returns parent entries then child entries forcustomManagers.The org preset's automerge rules do not match
custom.regex, so future releases open a reviewable PR rather than automerging.CI on the PR confirms it end to end:
gitleaks version→8.30.1,no leaks found.Two things found alongside
.pre-commit-config.yamlhad the same rot. It pinnedrev: v8.21.2for the same hook, and Renovate'spre-commitmanager is off by default, so that file was not in Detected Dependencies at all — the same defect on the developer-machine gate. fix(gitleaks): bump the org scanner to 8.30.1 and make the pin Renovate-trackable #31 enables the manager and bumps it. This repo is the only caller carrying that file.curl … | tar -xzinto/usr/local/bin, and Renovate cannot pin a digest for a tarball URL, though releases publishgitleaks_<v>_checksums.txt. Different defect, deliberately left out of fix(gitleaks): bump the org scanner to 8.30.1 and make the pin Renovate-trackable #31.One behaviour change to know about:
--max-decode-depthdefaults to5in 8.30.1 versus0in 8.21.2, so nested base64 is now decoded and scanned. It produced no new findings on any caller, but it is the likeliest source of a future false positive.fix(gitleaks): bump the org scanner to 8.30.1 and make the pin Renova…