Skip to content

Commit 16e045d

Browse files
fix(security): upgrade secret scanning from retired trufflehog to gitleaks (#49)
**This repo's only leak scanning was an inline trufflehog job** — and trufflehog was retired estate-wide. The standards secret-scanner reusable records the ruling in its own header: > *"Trufflehog was removed as redundant; gitleaks catches what we need"* > *"Trufflehog removed: gitleaks provides sufficient coverage at lower cost."* ## This is an upgrade, not a removal — and that distinction is the point A sweep is currently deleting leftover trufflehog steps across the estate. **This repo was deliberately excluded from it.** With no other scanner present, deleting would have left it with **no secret scanning at all**. Estate-wide measurement, all 424 repos (364 have workflows): | | count | treatment | |---|---:|---| | gitleaks only | 170 (47%) | left alone | | trufflehog **and** gitleaks | 73 (20%) | straggler deleted | | **trufflehog only** | **33 (9%)** | **this PR — upgraded** | | neither | 88 (24%) | still open | ## What actually changes - **gitleaks over the whole working tree** with `--no-git`, exiting non-zero on a finding. The inline job scanned a `base..head` diff — narrower than the tree. - The reusable's **`rust-secrets` and `shell-secrets`** jobs come along with it, so the local `rust-secrets` grep is no longer needed separately. - A **pinned, checksum-verified gitleaks binary** rather than an action that injects one. ## Two details that would fail silently if omitted **`secrets: inherit` is required**, and is included. Without it the gitleaks action's inner `secrets.GITHUB_TOKEN` is empty and the scan **silently degrades** — a quiet failure of exactly the kind this campaign exists to remove. **Where an `actions.lock` exists it gains a hand-authored `[]` entry** for this file. `gh actions-lock` **skips reusable-workflow callers**, and without the entry the workflow is rejected as `startup_failure` with no log and no check run — which reads as "the change broke CI" rather than "a lockfile entry is missing". ## No context is stranded The workflow's `name:` is preserved verbatim. Job-level context names *do* change, since they now come from the reusable — this repo's rulesets were checked first and require no secret-scanning context, so nothing is left pointing at a string that will never report. Found during the 2026-08-05 estate CI/CD census. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Signed-off-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent da663b6 commit 16e045d

1 file changed

Lines changed: 12 additions & 55 deletions

File tree

Lines changed: 12 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,22 @@
11
# SPDX-License-Identifier: MPL-2.0
2-
# Prevention workflow - scans for hardcoded secrets before they reach main
3-
name: Secret Scanner
2+
# Calls the estate's shared secret scanner (gitleaks + rust-secrets +
3+
# shell-secrets). Replaces an inline trufflehog job: trufflehog was retired
4+
# estate-wide as redundant, and this repo had no other leak scanning, so the
5+
# scanner is UPGRADED here rather than removed.
6+
#
7+
# `secrets: inherit` is REQUIRED — without it the gitleaks action's inner
8+
# secrets.GITHUB_TOKEN is empty and the scan silently degrades.
9+
name: 'Secret Scanner'
410
on:
511
pull_request:
612
push:
7-
branches: [main]
8-
# Estate guardrail: cancel superseded runs so re-pushes / rebased PR
9-
# updates do not pile up queued runs against the shared account-wide
10-
# Actions concurrency pool. Applied only to read-only check workflows
11-
# (no publish/mutation), so cancelling a superseded run is always safe.
13+
branches: [main, master]
1214
concurrency:
1315
group: ${{ github.workflow }}-${{ github.ref }}
1416
cancel-in-progress: true
1517
permissions:
16-
actions: read
1718
contents: read
1819
jobs:
19-
trufflehog:
20-
runs-on: ubuntu-latest
21-
timeout-minutes: 15
22-
steps:
23-
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4
24-
with:
25-
fetch-depth: 0 # Full history for scanning
26-
- name: TruffleHog Secret Scan
27-
uses: trufflesecurity/trufflehog@6c05c4a00b91aa542267d8e32a8254774799d68d # v3
28-
with:
29-
# The v3 action injects --fail automatically on pull_request events.
30-
# Passing --fail here triggers "flag 'fail' cannot be repeated".
31-
extra_args: --only-verified
32-
# Rust-specific: Check for hardcoded crypto values
33-
rust-secrets:
34-
runs-on: ubuntu-latest
35-
timeout-minutes: 15
36-
steps:
37-
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4
38-
- name: Check for hardcoded secrets in Rust
39-
run: |
40-
if ! find . -name Cargo.toml -not -path './target/*' -print -quit | grep -q .; then
41-
echo 'No Cargo.toml found — skipping Rust secrets check'
42-
exit 0
43-
fi
44-
# Patterns that suggest hardcoded secrets
45-
PATTERNS=(
46-
'const.*SECRET.*=.*"'
47-
'const.*KEY.*=.*"[a-zA-Z0-9]{16,}"'
48-
'const.*TOKEN.*=.*"'
49-
'let.*api_key.*=.*"'
50-
'HMAC.*"[a-fA-F0-9]{32,}"'
51-
'password.*=.*"[^"]+"'
52-
)
53-
54-
found=0
55-
for pattern in "${PATTERNS[@]}"; do
56-
if grep -rn --include="*.rs" -E "$pattern" src/; then
57-
echo "WARNING: Potential hardcoded secret found matching: $pattern"
58-
found=1
59-
fi
60-
done
61-
62-
if [ $found -eq 1 ]; then
63-
echo "::error::Potential hardcoded secrets detected. Use environment variables instead."
64-
exit 1
65-
fi
20+
scan:
21+
uses: hyperpolymath/standards/.github/workflows/secret-scanner-reusable.yml@bd0df9ead7faf0cdfe0e13e7966d91e28d0101d4
22+
secrets: inherit

0 commit comments

Comments
 (0)