diff --git a/.github/workflows/secret-scanning.yml b/.github/workflows/secret-scanning.yml index a107d13c..086c6842 100644 --- a/.github/workflows/secret-scanning.yml +++ b/.github/workflows/secret-scanning.yml @@ -20,9 +20,49 @@ jobs: fetch-depth: 0 - name: Scan for secrets + id: scan uses: trufflesecurity/trufflehog@6f3c981e7b77f235fd2702dd74af25fc4b72bf11 # v3.96.0 with: - extra_args: --results=verified,unknown + # Tag as published on ghcr — no leading "v" (v3.96.0 is a 404 there, + # even though the action's own git tag does carry the v). + version: 3.96.0 + # --exclude-detectors=lob: the Lob detector's pattern is + # `\b((live|test)_[a-zA-Z0-9_]{35})\b` with no keyword requirement, so it + # matches any 40-character `test_*` Python identifier. It also treats + # HTTP 403/422 from api.lob.com as "verified", so those match as verified + # secrets. ADK does not use Lob, so there is no coverage to lose. + extra_args: --results=verified,unknown --exclude-detectors=lob + + # The action runs TruffleHog with --github-actions, whose printer emits only + # "Found verified result" — the file and line go into annotation + # metadata that never renders in the log, and the match is never printed at + # all. That is not enough to tell a leak from a false positive. Re-run on + # failure with --json and report file, line, commit and a truncated match. + # Only a 12-char prefix is printed: enough to identify the string, not to + # use it. This step exits 0 — the gate above already failed the job. + - name: Report what was flagged + if: failure() && steps.scan.outcome == 'failure' + env: + BASE: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before }} + HEAD: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} + run: | + docker run --rm -v .:/tmp -w /tmp \ + ghcr.io/trufflesecurity/trufflehog:3.96.0 \ + git file:///tmp/ \ + --since-commit "$BASE" \ + --branch "$HEAD" \ + --no-update \ + --json \ + --results=verified,unknown \ + --exclude-detectors=lob \ + | jq -r 'select(.DetectorName) | [ + "──────────────────────────────────────────", + "detector: \(.DetectorName) [\(if .Verified then "verified" else "unverified" end)]", + "file: \(.SourceMetadata.Data.Git.file)", + "line: \(.SourceMetadata.Data.Git.line)", + "commit: \(.SourceMetadata.Data.Git.commit[0:12]) by \(.SourceMetadata.Data.Git.email)", + "match: \(.Raw[0:12])… (\(.Raw | length) chars)" + ] | join("\n")' # Direct pushes to main skip PR review entirely, so the Actions tab may be # the only signal. Open an issue and assign the pusher so it can't be missed.