Scans the full git history on push, pull request and weekly, so a credential that was committed and later removed is still detected. The scanner archive is pinned by version and verified by SHA-256 before it runs, and matched values are redacted so they never reach the CI log. The accompanying allowlist covers two redaction test fixtures that assert secret-shaped input is masked. Each entry is pinned to an exact commit, file, rule and line, so a real secret added to those files later is still reported.
This commit is contained in:
1 parent
a9e8287065
commit
6ccff1c8df
2 files changed
+64
No files matched your search
@@ -0,0 +1,51 @@
|
||||
name: secret-scan
|
||||
|
||||
# Scans the FULL git history, not just the working tree: a credential that was
|
||||
# committed and later deleted is still published, and only a history scan sees it.
|
||||
# The weekly run exists because new detector rules find old secrets that passed
|
||||
# when they were first pushed.
|
||||
#
|
||||
# This repository carries a .gitleaksignore: its tests assert that a redaction
|
||||
# function masks secret-shaped input, so the fixtures trip the scanner. Those
|
||||
# entries are pinned per commit, file, rule and line, never by directory.
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: "0 5 * * 1"
|
||||
|
||||
jobs:
|
||||
gitleaks:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out full history
|
||||
# Pinned to a commit, not a mutable tag: a security job must not silently
|
||||
# change what it runs when upstream retags.
|
||||
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install pinned Gitleaks
|
||||
env:
|
||||
GITLEAKS_VERSION: "8.30.1"
|
||||
GITLEAKS_SHA256: "551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb"
|
||||
run: |
|
||||
set -euo pipefail
|
||||
archive="gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz"
|
||||
curl -fsSL -o "${archive}" \
|
||||
"https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/${archive}"
|
||||
# Fail loudly on any mismatch rather than scanning with an unverified binary.
|
||||
printf '%s %s\n' "${GITLEAKS_SHA256}" "${archive}" | sha256sum -c -
|
||||
tar -xzf "${archive}" gitleaks
|
||||
chmod 0755 gitleaks
|
||||
./gitleaks version
|
||||
|
||||
- name: Scan full history for secrets
|
||||
# --redact=100 keeps matched values out of the CI log, which is itself
|
||||
# readable by anyone who can see the run.
|
||||
run: ./gitleaks git . --redact=100 --no-banner --exit-code 1
|
||||
|
||||
- name: Remove the downloaded scanner
|
||||
if: always()
|
||||
run: rm -f gitleaks gitleaks_*.tar.gz
|
||||
@@ -0,0 +1,13 @@
|
||||
# Allowlisted Gitleaks fingerprints.
|
||||
#
|
||||
# Both entries are deliberate test fixtures for this project's own redaction
|
||||
# function, not credentials: each asserts that a secret-shaped input is masked.
|
||||
# They are history-only -- the current tests assemble those strings at runtime --
|
||||
# and a historical commit cannot be cleaned without rewriting history, which is
|
||||
# not warranted for fixture data.
|
||||
#
|
||||
# Each entry is pinned to an exact commit, file, rule and line rather than
|
||||
# ignoring the tests/ directory, so a real secret committed to the same files
|
||||
# later is still reported.
|
||||
a9e828706529bab38759f9a8bea4aafc721853aa:tests/test_redact.py:generic-api-key:30
|
||||
a9e828706529bab38759f9a8bea4aafc721853aa:tests/test_judge.py:generic-api-key:71
|
||||
Reference in new issue
Block a user