diff --git a/.github/workflows/secret-scan.yml b/.github/workflows/secret-scan.yml new file mode 100644 index 0000000..835e307 --- /dev/null +++ b/.github/workflows/secret-scan.yml @@ -0,0 +1,63 @@ +name: "Security Gate: Secret Scanning" + +on: + push: + branches: ["**"] + pull_request: + branches: [main, master] + +permissions: {} + +jobs: + trufflehog: + name: Scan for Verified Secrets + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout code + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Resolve scan range + id: scan_range + env: + EVENT_NAME: ${{ github.event_name }} + PR_BASE_SHA: ${{ github.event.pull_request.base.sha }} + PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }} + PUSH_BASE_SHA: ${{ github.event.before }} + PUSH_HEAD_SHA: ${{ github.sha }} + DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + run: | + set -euo pipefail + zero_sha="0000000000000000000000000000000000000000" + + if [[ "$EVENT_NAME" == "pull_request" ]]; then + base="$PR_BASE_SHA" + head="$PR_HEAD_SHA" + else + base="$PUSH_BASE_SHA" + head="$PUSH_HEAD_SHA" + if [[ -z "$base" || "$base" == "$zero_sha" ]]; then + base="origin/$DEFAULT_BRANCH" + fi + fi + + echo "base=$base" >> "$GITHUB_OUTPUT" + echo "head=$head" >> "$GITHUB_OUTPUT" + + - name: TruffleHog OSS + id: trufflehog + uses: trufflesecurity/trufflehog@v3.95.2 + with: + path: ./ + base: ${{ steps.scan_range.outputs.base }} + head: ${{ steps.scan_range.outputs.head }} + extra_args: --only-verified --debug + + - name: Notify on failure + if: steps.trufflehog.outcome == 'failure' + run: | + echo "::error::Verified secrets found. Rotate the credential before merging." + exit 1