Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 33 additions & 5 deletions .github/workflows/gitleaks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,18 +73,46 @@ jobs:
RANGE=""
fi

# --redact: values never reach the log. --report-path: the JSON says
# WHICH file, line and commit, uploaded below. A scanner that only
# says "1 leak found" sends you hunting through the whole history.
COMMON="--source=. --redact --report-format json --report-path gitleaks-report.json"
if [ -n "$RANGE" ]; then
echo "scanning range $RANGE"
/tmp/gitleaks detect --source=. --redact --log-opts="$RANGE"
/tmp/gitleaks detect $COMMON --log-opts="$RANGE"
else
echo "scanning the ENTIRE history"
/tmp/gitleaks detect --source=. --redact
/tmp/gitleaks detect $COMMON
fi

- name: What to do if that failed
- name: Where the findings are
if: failure()
run: |
echo "::error::A secret was found, or the scan could not run. Either way this does not merge."
echo "If a credential was found: it is compromised. Remove it, ROTATE it (git history keeps the old value),"
echo "and confirm .gitignore covers it. Rewriting history alone does NOT make a leaked key safe."
# jq, not a heredoc: a heredoc body has to start at column 0, which
# terminates the YAML block scalar and makes this whole workflow
# unparseable. That shipped once and the run failed with no jobs at
# all — a broken scanner reads as a failing scan, which is at least
# loud, but do not do it again.
if [ -s gitleaks-report.json ]; then
echo "--- findings (file, line, commit — values stay redacted) ---"
jq -r '.[] | " \(.RuleID) \(.File):\(.StartLine) commit \(.Commit[0:10]) \(.Date) entropy \(.Entropy)"' \
gitleaks-report.json || cat gitleaks-report.json
fi
echo ""
echo "If it is a real credential: it is compromised. Remove it, ROTATE it (git history keeps"
echo "the old value), and confirm .gitignore covers it. Rewriting history alone does NOT make"
echo "a leaked key safe — the object stays retrievable by hash."
echo ""
echo "If it is a false positive: allowlist THAT FINDING by fingerprint in .gitleaks.toml,"
echo "with a line saying why. Never allowlist a path, an extension or a whole rule — that is"
echo "how a scanner goes blind without anyone noticing."
exit 1

- name: Keep the report
if: failure()
uses: actions/upload-artifact@v4
with:
name: gitleaks-report-${{ github.run_id }}
path: gitleaks-report.json
if-no-files-found: ignore
Loading