|
| 1 | +name: Secret scan |
| 2 | + |
| 3 | +# This repo is public. These jobs answer "has a credential reached the |
| 4 | +# public internet," on the push itself, not on some later PR review -- |
| 5 | +# there is no local pre-commit hook here yet to catch it first. |
| 6 | +# |
| 7 | +# Why no paths: filter, though it would cut run count: gitleaks and |
| 8 | +# trufflehog both scan FULL history (fetch-depth: 0) on every run, so |
| 9 | +# filtering by one push's changed files would skip a whole-history scan |
| 10 | +# just because the newest commit only touched a README. A path allowlist |
| 11 | +# would also gate the scan on the same "files we thought about" list whose |
| 12 | +# gaps are the actual leak path. |
| 13 | +# |
| 14 | +# No sops/encrypted-secrets job here (unlike dotfiles/symphony): this repo |
| 15 | +# manages no encrypted secrets. Add one if that changes. |
| 16 | + |
| 17 | +on: |
| 18 | + push: |
| 19 | + branches: ['**'] |
| 20 | + workflow_dispatch: |
| 21 | + schedule: |
| 22 | + # Weekly re-scan of unchanged history. Not redundant: trufflehog ships |
| 23 | + # new detectors continuously, so a commit that was clean last month can |
| 24 | + # be flagged this month by a detector that didn't exist then. |
| 25 | + - cron: "41 9 * * 1" |
| 26 | + |
| 27 | +# A session that pushes four times in two minutes only needs the newest |
| 28 | +# commit scanned; superseded runs are cancelled. Scheduled runs are exempt |
| 29 | +# -- the weekly sweep of unchanged history is the one run that must not be |
| 30 | +# cancelled by an unrelated push landing on the same ref. That requires a |
| 31 | +# separate group per event kind (CodeRabbit, 2026-09-05): the schedule fires |
| 32 | +# against main, so a push to main used to share gitleaks' group with an |
| 33 | +# in-progress scheduled run, and cancel-in-progress on the NEW (push) run is |
| 34 | +# what cancels the OLD (scheduled) one -- the scheduled run's own |
| 35 | +# cancel-in-progress never got a say. |
| 36 | +concurrency: |
| 37 | + group: secret-scan-${{ github.ref }}-${{ github.event_name == 'push' && 'push' || github.run_id }} |
| 38 | + cancel-in-progress: ${{ github.event_name == 'push' }} |
| 39 | + |
| 40 | +permissions: |
| 41 | + contents: read |
| 42 | + |
| 43 | +jobs: |
| 44 | + # gitleaks (full history) + trufflehog (verified-live only), both shared |
| 45 | + # with dotfiles/symphony/space-weather via mark-brannan/.github -- see |
| 46 | + # that repo's secret-scan.yml for what each job does and why. This repo |
| 47 | + # has no .gitleaks.toml, so no gitleaks-config input is passed. |
| 48 | + secret-scan: |
| 49 | + permissions: |
| 50 | + contents: read |
| 51 | + # @main, deliberately -- same-owner trust, matching every other caller |
| 52 | + # of a mark-brannan/.github workflow. CodeRabbit flagged this as |
| 53 | + # unpinned (2026-09-05, zizmor's unpinned-uses); considered and |
| 54 | + # reverted (2026-09-05): the threat that lint guards against is a |
| 55 | + # compromised upstream *maintainer*, which doesn't apply when the |
| 56 | + # upstream is your own repo. Pinning would only buy protection |
| 57 | + # against mistakes in the shared workflow, at the cost of a manual |
| 58 | + # pin-bump PR per caller for every future fix. |
| 59 | + uses: mark-brannan/.github/.github/workflows/secret-scan.yml@main |
0 commit comments