Skip to content

Commit f4447fb

Browse files
fix(security): upgrade secret scanning from retired trufflehog to gitleaks (#56)
**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 4006178 commit f4447fb

1 file changed

Lines changed: 12 additions & 56 deletions

File tree

Lines changed: 12 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,22 @@
11
# SPDX-License-Identifier: MPL-2.0
2-
# // Copyright (c) Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
3-
# SPDX-License-Identifier: MPL-2.0
4-
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'
510
on:
611
pull_request:
712
push:
8-
branches: [main]
9-
# Estate guardrail: cancel superseded runs so re-pushes / rebased PR
10-
# updates do not pile up queued runs against the shared account-wide
11-
# Actions concurrency pool. Applied only to read-only check workflows
12-
# (no publish/mutation), so cancelling a superseded run is always safe.
13+
branches: [main, master]
1314
concurrency:
1415
group: ${{ github.workflow }}-${{ github.ref }}
1516
cancel-in-progress: true
1617
permissions:
17-
actions: read
1818
contents: read
1919
jobs:
20-
trufflehog:
21-
runs-on: ubuntu-latest
22-
timeout-minutes: 15
23-
steps:
24-
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4
25-
with:
26-
fetch-depth: 0 # Full history for scanning
27-
- name: TruffleHog Secret Scan
28-
uses: trufflesecurity/trufflehog@6c05c4a00b91aa542267d8e32a8254774799d68d # v3
29-
with:
30-
# The v3 action injects --fail automatically on pull_request events.
31-
# Passing --fail here triggers "flag 'fail' cannot be repeated".
32-
extra_args: --only-verified
33-
# Rust-specific: Check for hardcoded crypto values
34-
rust-secrets:
35-
runs-on: ubuntu-latest
36-
timeout-minutes: 15
37-
steps:
38-
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4
39-
- name: Check for hardcoded secrets in Rust
40-
run: |
41-
if ! find . -name Cargo.toml -not -path './target/*' -print -quit | grep -q .; then
42-
echo 'No Cargo.toml found — skipping Rust secrets check'
43-
exit 0
44-
fi
45-
# Patterns that suggest hardcoded secrets
46-
PATTERNS=(
47-
'const.*SECRET.*=.*"'
48-
'const.*KEY.*=.*"[a-zA-Z0-9]{16,}"'
49-
'const.*TOKEN.*=.*"'
50-
'let.*api_key.*=.*"'
51-
'HMAC.*"[a-fA-F0-9]{32,}"'
52-
'password.*=.*"[^"]+"'
53-
)
54-
55-
found=0
56-
for pattern in "${PATTERNS[@]}"; do
57-
if grep -rn --include="*.rs" -E "$pattern" src/; then
58-
echo "WARNING: Potential hardcoded secret found matching: $pattern"
59-
found=1
60-
fi
61-
done
62-
63-
if [ $found -eq 1 ]; then
64-
echo "::error::Potential hardcoded secrets detected. Use environment variables instead."
65-
exit 1
66-
fi
20+
scan:
21+
uses: hyperpolymath/standards/.github/workflows/secret-scanner-reusable.yml@bd0df9ead7faf0cdfe0e13e7966d91e28d0101d4
22+
secrets: inherit

0 commit comments

Comments
 (0)