diff --git a/.github/workflows/org-required-trufflehog.yml b/.github/workflows/org-required-trufflehog.yml index 4d09a4b..454f075 100644 --- a/.github/workflows/org-required-trufflehog.yml +++ b/.github/workflows/org-required-trufflehog.yml @@ -18,7 +18,7 @@ permissions: jobs: secret-scan: name: TruffleHog Secret Scan - uses: grafana/security-github-actions/.github/workflows/reusable-trufflehog.yml@main + uses: grafana/security-github-actions/.github/workflows/reusable-trufflehog.yml@feat/upload-trufflehog-json-artifact with: # Monitoring mode - no blocking, just reporting fail-on-verified: "false" # Don't block on verified secrets (monitoring only) diff --git a/.github/workflows/reusable-trufflehog.yml b/.github/workflows/reusable-trufflehog.yml index 9c18b91..c32fdff 100644 --- a/.github/workflows/reusable-trufflehog.yml +++ b/.github/workflows/reusable-trufflehog.yml @@ -85,6 +85,9 @@ jobs: # Process results if [[ -s results.ndjson ]]; then grep -v '^$' results.ndjson | jq -s '.' > results.json 2>/dev/null || echo "[]" > results.json + else + # Ensure results.json exists even if no results + echo "[]" > results.json fi # Count secrets @@ -188,14 +191,101 @@ jobs: fi } > trufflehog_scan.txt + - name: Verify JSON file exists + if: always() + run: | + if [[ -f "results.json" ]]; then + echo "✅ results.json exists" + echo "File size: $(wc -c < results.json) bytes" + echo "JSON validity check:" + if jq empty results.json 2>/dev/null; then + echo "✅ Valid JSON" + echo "Number of findings: $(jq '. | length' results.json)" + else + echo "❌ Invalid JSON" + fi + else + echo "❌ results.json does not exist" + fi + + - name: Prepare artifacts for upload + if: always() + run: | + # Ensure results.json exists + if [[ ! -f "results.json" ]]; then + echo "[]" > results.json + echo "Created empty results.json" + fi + + # Create artifacts directory and copy files + mkdir -p trufflehog-artifacts + + # Copy text report + if [[ -f "trufflehog_scan.txt" ]]; then + cp trufflehog_scan.txt trufflehog-artifacts/ + echo "✓ Copied trufflehog_scan.txt" + else + echo "⚠ trufflehog_scan.txt not found" + fi + + # Copy JSON results + if [[ -f "results.json" ]]; then + cp results.json trufflehog-artifacts/ + echo "✓ Copied results.json" + else + echo "⚠ results.json not found, creating empty one" + echo "[]" > trufflehog-artifacts/results.json + fi + + echo "" + echo "Files in artifacts directory:" + ls -lah trufflehog-artifacts/ + - name: Upload scan results uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 if: always() with: name: trufflehog_scan - path: trufflehog_scan.txt + path: trufflehog-artifacts/ retention-days: 30 + - name: Setup Python for Grafana integration + if: ${{ !cancelled() && (secrets.LOKI_URL != '' || secrets.PROMETHEUS_PUSHGATEWAY_URL != '') }} + uses: actions/setup-python@0b6a380b5a7827e48e69b2e0e596c5c8c2b0e0b0 # v5.1.0 + with: + python-version: '3.x' + + - name: Install Python dependencies + if: ${{ !cancelled() && (secrets.LOKI_URL != '' || secrets.PROMETHEUS_PUSHGATEWAY_URL != '') }} + run: | + pip install requests + + - name: Send findings to Loki + if: ${{ !cancelled() && secrets.LOKI_URL != '' }} + continue-on-error: true + env: + LOKI_URL: ${{ secrets.LOKI_URL }} + LOKI_USERNAME: ${{ secrets.LOKI_USERNAME }} + LOKI_PASSWORD: ${{ secrets.LOKI_PASSWORD }} + REPOSITORY: ${{ github.repository }} + COMMIT_SHA: ${{ github.sha }} + BRANCH: ${{ github.ref_name }} + TRUFFLEHOG_RESULTS_FILE: results.json + run: | + python trufflehog/send-to-loki.py + + - name: Send metrics to Prometheus + if: ${{ !cancelled() && secrets.PROMETHEUS_PUSHGATEWAY_URL != '' }} + continue-on-error: true + env: + PROMETHEUS_PUSHGATEWAY_URL: ${{ secrets.PROMETHEUS_PUSHGATEWAY_URL }} + REPOSITORY: ${{ github.repository }} + COMMIT_SHA: ${{ github.sha }} + BRANCH: ${{ github.ref_name }} + TRUFFLEHOG_RESULTS_FILE: results.json + run: | + python trufflehog/send-to-prometheus.py + - name: Check failure policy env: FAIL_ON_VERIFIED: ${{ inputs.fail-on-verified }}