|
10 | 10 | security-scan: |
11 | 11 | runs-on: ubuntu-latest |
12 | 12 | name: Security Scanning |
| 13 | + env: |
| 14 | + GITLEAKS_VERSION: "8.28.0" # pin gitleaks version |
| 15 | + GITLEAKS_CONFIG: ".gitleaks.toml" # config picked up automatically by gitleaks |
13 | 16 |
|
14 | 17 | steps: |
15 | 18 | - name: Checkout code |
|
20 | 23 | - name: TruffleHog OSS Secret Scanning |
21 | 24 | uses: trufflesecurity/trufflehog@main |
22 | 25 | with: |
23 | | - # Scan the entire repository |
| 26 | + # Scan the entire repository |
24 | 27 | path: ./ |
25 | | - # Only show verified secrets and unknown (high confidence) |
| 28 | + # Only show verified secrets and unknown (high confidence) |
26 | 29 | extra_args: --results=verified,unknown |
27 | 30 |
|
28 | 31 | - name: Setup Python for detect-secrets |
|
79 | 82 |
|
80 | 83 | echo "✅ Custom secret checks passed!" |
81 | 84 |
|
| 85 | + # ---- Gitleaks CLI pinned to 8.28.0 (no SARIF) ---- |
| 86 | + - name: Download Gitleaks v8.28.0 (linux_x64) + verify checksum |
| 87 | + run: | |
| 88 | + set -euo pipefail |
| 89 | + TAR="gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" |
| 90 | + BASE="https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}" |
| 91 | +
|
| 92 | + echo "Downloading $TAR..." |
| 93 | + curl -sSL "${BASE}/${TAR}" -o gitleaks.tar.gz |
| 94 | + curl -sSL "${BASE}/gitleaks_${GITLEAKS_VERSION}_checksums.txt" -o checksums.txt |
| 95 | +
|
| 96 | + EXPECTED=$(grep "$TAR" checksums.txt | awk '{print $1}') |
| 97 | + ACTUAL=$(sha256sum gitleaks.tar.gz | awk '{print $1}') |
| 98 | + [ "$EXPECTED" = "$ACTUAL" ] || { echo "Checksum mismatch!"; exit 1; } |
| 99 | +
|
| 100 | + tar -xzf gitleaks.tar.gz gitleaks |
| 101 | + chmod +x gitleaks |
| 102 | + ./gitleaks version |
| 103 | +
|
| 104 | + # PRs: stage only changed files and scan staged diff (blocks on new leaks) |
| 105 | + - name: Run Gitleaks on staged PR changes (blocking) |
| 106 | + if: ${{ github.event_name == 'pull_request' }} |
| 107 | + run: | |
| 108 | + set -euo pipefail |
| 109 | + # Ensure base is present and compute changed files |
| 110 | + git fetch --no-tags --prune --depth=1 origin +refs/heads/${{ github.base_ref }}:refs/remotes/origin/${{ github.base_ref }} |
| 111 | + git diff --name-only origin/${{ github.base_ref }}..HEAD > /tmp/changed_files.txt |
| 112 | + if [ -s /tmp/changed_files.txt ]; then |
| 113 | + xargs -a /tmp/changed_files.txt git add |
| 114 | + ./gitleaks protect --staged --no-banner --redact |
| 115 | + xargs -a /tmp/changed_files.txt git reset |
| 116 | + else |
| 117 | + echo "No changed files; skipping." |
| 118 | + fi |
| 119 | +
|
| 120 | + # Non-PR runs (e.g., merge_group/push): full scan, do not fail the job |
| 121 | + - name: Run Gitleaks full scan (non-blocking) |
| 122 | + if: ${{ github.event_name != 'pull_request' }} |
| 123 | + run: | |
| 124 | + ./gitleaks detect \ |
| 125 | + --source . \ |
| 126 | + --no-banner \ |
| 127 | + --redact || true |
| 128 | +
|
82 | 129 | # Optional: Add Semgrep for additional security analysis |
83 | 130 | semgrep: |
84 | 131 | runs-on: ubuntu-latest |
|
92 | 139 | - name: Run Semgrep |
93 | 140 | uses: returntocorp/semgrep-action@v1 |
94 | 141 | with: |
95 | | - # Run security-focused rules |
| 142 | + # Run security-focused rules |
96 | 143 | config: >- |
97 | 144 | p/security-audit |
98 | 145 | p/secrets |
|
0 commit comments