Repository navigation
120 lines (103 loc) · 4.31 KB
/
Copy pathGitleaks.yml
File metadata and controls
120 lines (103 loc) · 4.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
name: Gitleaks secrets scan
on:
pull_request:
branches:
- main
permissions:
issues: write
pull-requests: write
contents: read
jobs:
gitleaks:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Required to get full commit history for diffing
- name: Get base and head commit SHAs
run: |
echo "BASE_SHA=${{ github.event.pull_request.base.sha }}" >> $GITHUB_ENV
echo "HEAD_SHA=${{ github.event.pull_request.head.sha }}" >> $GITHUB_ENV
- name: Run Gitleaks on PR changes via Docker
run: |
docker run --rm -v $(pwd):/repo -w /repo zricethezav/gitleaks:latest detect \
--config="/repo/.gitleaks.toml" \
--log-opts="--no-merges $BASE_SHA..$HEAD_SHA" \
--verbose \
--exit-code=0 \
--report-format=json \
--report-path="/repo/gitleaks-report.json" \
--redact
- name: Upload Gitleaks report
uses: actions/upload-artifact@v4
with:
name: gitleaks-report
path: gitleaks-report.json
- name: Format and comment findings on PR
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
if [ ! -f gitleaks-report.json ]; then
echo "Report file not found!"
exit 1
fi
FINDINGS_JSON=$(cat gitleaks-report.json)
COUNT=$(echo "$FINDINGS_JSON" | jq 'length')
SHA="${{ github.event.pull_request.head.sha }}"
REPO="${{ github.repository }}"
PR_NUMBER="${{ github.event.pull_request.number }}"
MAX=10
if [ "$COUNT" -gt 0 ]; then
COMMENT="**🔐 Gitleaks Findings: $COUNT issue(s) detected**\n\n"
i=0
while [ "$i" -lt "$COUNT" ] && [ "$i" -lt "$MAX" ]; do
ITEM=$(echo "$FINDINGS_JSON" | jq ".[$i]")
RULE=$(echo "$ITEM" | jq -r '.RuleID')
DESC=$(echo "$ITEM" | jq -r '.Description')
FILE=$(echo "$ITEM" | jq -r '.File')
LINE=$(echo "$ITEM" | jq -r '.Line')
LINK="https://github.com/$REPO/blob/$SHA/$FILE#L$LINE"
SECRET_MASKED="**********"
COMMENT+="🔸 **Rule**: \`$RULE\`\n"
COMMENT+="📄 **File**: \`$FILE:$LINE\`\n"
COMMENT+="📝 **Description**: $DESC\n"
COMMENT+="🔑 **Secret**: \`$SECRET_MASKED\`\n"
COMMENT+="🔗 **Path**: [$FILE:$LINE]($LINK)\n\n"
i=$((i + 1))
done
if [ "$COUNT" -gt "$MAX" ]; then
COMMENT+="...and more. Only showing first $MAX findings.\n"
fi
else
COMMENT="✅ **Gitleaks Findings:** No secrets detected. Safe to proceed!"
fi
# Escape newlines for GitHub API
COMMENT=$(echo "$COMMENT" | sed ':a;N;$!ba;s/\n/\\n/g')
curl -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
-d "{\"body\":\"$COMMENT\"}" \
"https://api.github.com/repos/${REPO}/issues/${PR_NUMBER}/comments"
- name: Fail if secrets were found
# The scan step above runs with --exit-code=0 so it always reaches
# the comment step regardless of findings - reporting and
# enforcement are deliberately separate steps. This is the
# enforcement half: without it, this whole workflow only ever
# comments and never blocks a PR, even when it finds a real
# secret. gitleaks-auto-redact.yml pushes an auto-fix commit for
# fake secrets in generated code, which re-triggers this workflow
# and clears this failure on its own once that commit lands - a
# failure here that persists past that point means a human needs
# to look at it.
run: |
if [ ! -f gitleaks-report.json ]; then
echo "Report file not found!"
exit 1
fi
COUNT=$(jq 'length' gitleaks-report.json)
if [ "$COUNT" -gt 0 ]; then
echo "::error::Gitleaks found $COUNT secret(s) in this PR - see the PR comment above, or download the gitleaks-report artifact."
exit 1
fi
echo "No secrets detected - safe to proceed."