Skip to content

Commit 4f60581

Browse files
authored
Merge pull request #31 from marklogic/brijesh-dev
PDP-684 : Reverting my changes for trufflehog
2 parents 46305c1 + a7b8ecd commit 4f60581

File tree

1 file changed

+59
-31
lines changed

1 file changed

+59
-31
lines changed

.github/workflows/trufflehog-scan.yml

Lines changed: 59 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,15 @@ permissions:
99
contents: read
1010
pull-requests: write
1111

12+
# Default exclusion patterns (regex format)
13+
# Supports: exact filenames, wildcards, regex patterns
14+
# Examples:
15+
# Exact file: ^config/settings\.json$
16+
# Directory: ^node_modules/
17+
# Extension: \.lock$
18+
# Wildcard: .*\.min\.js$
19+
# Regex: ^src/test/.*_test\.py$
20+
1221
env:
1322
DEFAULT_EXCLUDES: |
1423
^node_modules/
@@ -30,19 +39,28 @@ jobs:
3039
- name: Checkout repository
3140
uses: actions/checkout@v4
3241
with:
33-
ref: ${{ github.event.pull_request.head.sha }}
34-
fetch-depth: 2
42+
fetch-depth: 0
43+
44+
- name: Fetch PR head commits
45+
if: github.event_name != 'workflow_dispatch'
46+
run: |
47+
# Fetch PR commits using GitHub's merge ref (works for all PRs including forks)
48+
git fetch origin +refs/pull/${{ github.event.pull_request.number }}/head:refs/remotes/origin/pr-head
49+
echo "Fetched PR #${{ github.event.pull_request.number }} head commit: ${{ github.event.pull_request.head.sha }}"
3550
3651
- name: Setup exclude config
3752
id: config
3853
run: |
54+
# Always include default exclusions
3955
echo "Adding default exclusions"
4056
cat << 'EOF' > .trufflehog-ignore
4157
${{ env.DEFAULT_EXCLUDES }}
4258
EOF
4359
60+
# Append repo/org-level custom exclusions if defined
4461
if [ -n "${{ vars.TRUFFLEHOG_EXCLUDES }}" ]; then
4562
echo "Adding repo/org-level TRUFFLEHOG_EXCLUDES patterns"
63+
# Support both comma-separated and newline-separated patterns
4664
echo "${{ vars.TRUFFLEHOG_EXCLUDES }}" | tr ',' '\n' | sed '/^$/d' >> .trufflehog-ignore
4765
fi
4866
@@ -55,62 +73,49 @@ jobs:
5573
uses: trufflesecurity/trufflehog@main
5674
continue-on-error: true
5775
with:
58-
base: ${{ github.event.pull_request.head.sha }}~1
76+
base: ${{ github.event.pull_request.base.sha }}
5977
head: ${{ github.event.pull_request.head.sha }}
6078
extra_args: --json ${{ steps.config.outputs.exclude_args }}
6179

6280
- name: Parse scan results
6381
id: parse
6482
if: github.event_name != 'workflow_dispatch'
6583
run: |
84+
# Capture TruffleHog JSON output by re-running with same args
6685
echo "Parsing TruffleHog results..."
6786
6887
VERIFIED_COUNT=0
6988
UNVERIFIED_COUNT=0
7089
71-
# Get changed files list
72-
CHANGED_FILES=$(git diff --name-only --diff-filter=ACMR ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }})
73-
echo "Changed files:"
74-
echo "$CHANGED_FILES"
75-
76-
# Scan only HEAD commit (current state), not history
7790
SCAN_OUTPUT=$(docker run --rm -v "$(pwd)":/tmp -w /tmp \
78-
-e GIT_CONFIG_COUNT=2 \
79-
-e GIT_CONFIG_KEY_0=diff.renames \
80-
-e GIT_CONFIG_VALUE_0=false \
81-
-e GIT_CONFIG_KEY_1=diff.renameLimit \
82-
-e GIT_CONFIG_VALUE_1=0 \
8391
ghcr.io/trufflesecurity/trufflehog:latest \
8492
git file:///tmp/ \
85-
--since-commit ${{ github.event.pull_request.head.sha }}~1 \
93+
--since-commit ${{ github.event.pull_request.base.sha }} \
8694
--branch ${{ github.event.pull_request.head.sha }} \
87-
--max-depth=1 \
8895
--json \
8996
${{ steps.config.outputs.exclude_args }} \
9097
--no-update 2>/dev/null || true)
9198
99+
# Parse JSON lines and create GitHub annotations
92100
if [ -n "$SCAN_OUTPUT" ]; then
93101
while IFS= read -r line; do
102+
# Skip non-JSON lines (info logs)
94103
if ! echo "$line" | jq -e '.DetectorName' > /dev/null 2>&1; then
95104
continue
96105
fi
97106
98107
FILE=$(echo "$line" | jq -r '.SourceMetadata.Data.Git.file // "unknown"')
99-
100-
# Only report if file is in the changed files list
101-
if ! echo "$CHANGED_FILES" | grep -qxF "$FILE"; then
102-
continue
103-
fi
104-
105108
LINE_NUM=$(echo "$line" | jq -r '.SourceMetadata.Data.Git.line // 1')
106109
DETECTOR=$(echo "$line" | jq -r '.DetectorName // "Secret"')
107110
VERIFIED=$(echo "$line" | jq -r '.Verified // false')
108111
109112
if [ "$VERIFIED" == "true" ]; then
110113
VERIFIED_COUNT=$((VERIFIED_COUNT + 1))
111-
echo "::error file=${FILE},line=${LINE_NUM},title=${DETECTOR} [VERIFIED]::VERIFIED ACTIVE CREDENTIAL: ${DETECTOR} found in ${FILE} at line ${LINE_NUM}. Remove and rotate immediately!"
114+
# Error annotation for verified secrets
115+
echo "::error file=${FILE},line=${LINE_NUM},title=${DETECTOR} [VERIFIED]::VERIFIED ACTIVE CREDENTIAL: ${DETECTOR} found in ${FILE} at line ${LINE_NUM}. This secret is confirmed active. Remove and rotate immediately!"
112116
else
113117
UNVERIFIED_COUNT=$((UNVERIFIED_COUNT + 1))
118+
# Warning annotation for unverified secrets
114119
echo "::warning file=${FILE},line=${LINE_NUM},title=${DETECTOR} [Unverified]::Potential secret: ${DETECTOR} found in ${FILE} at line ${LINE_NUM}. Review and remove if this is a real credential."
115120
fi
116121
done <<< "$SCAN_OUTPUT"
@@ -128,14 +133,17 @@ jobs:
128133
UNVERIFIED=${{ steps.parse.outputs.unverified_count || 0 }}
129134
130135
if [ "$VERIFIED" -gt 0 ]; then
136+
# Verified secrets found - must fail
131137
echo "has_verified=true" >> $GITHUB_OUTPUT
132138
echo "has_secrets=true" >> $GITHUB_OUTPUT
133139
echo "description=Found ${VERIFIED} verified (active) secrets - action required" >> $GITHUB_OUTPUT
134140
elif [ "$UNVERIFIED" -gt 0 ]; then
141+
# Only unverified secrets - warn but pass
135142
echo "has_verified=false" >> $GITHUB_OUTPUT
136143
echo "has_secrets=true" >> $GITHUB_OUTPUT
137144
echo "description=Found ${UNVERIFIED} unverified potential secrets - review recommended" >> $GITHUB_OUTPUT
138145
else
146+
# No secrets
139147
echo "has_verified=false" >> $GITHUB_OUTPUT
140148
echo "has_secrets=false" >> $GITHUB_OUTPUT
141149
echo "description=No secrets detected in PR changes" >> $GITHUB_OUTPUT
@@ -154,6 +162,7 @@ jobs:
154162
const verifiedCount = '${{ steps.parse.outputs.verified_count }}' || '0';
155163
const unverifiedCount = '${{ steps.parse.outputs.unverified_count }}' || '0';
156164
165+
// Find existing comment
157166
const { data: comments } = await github.rest.issues.listComments({
158167
owner: context.repo.owner,
159168
repo: context.repo.repo,
@@ -165,26 +174,38 @@ jobs:
165174
166175
let body;
167176
if (!hasSecrets) {
177+
// No secrets found
168178
if (existing) {
169-
// Update to show secrets are now resolved (whether verified or unverified)
170-
body = `${commentMarker}
179+
// Check if existing comment was a critical/blocking one (had verified secrets)
180+
const wasBlocking = existing.body.includes('CRITICAL') || existing.body.includes(':rotating_light:');
181+
if (wasBlocking) {
182+
// Update to show verified secrets are now resolved
183+
body = `${commentMarker}
171184
## :white_check_mark: Secret Scanning Passed
185+
172186
**No secrets detected in this pull request.**
187+
173188
**Scanned commit:** \`${shortSha}\` ([${commitSha}](${{ github.server_url }}/${{ github.repository }}/commit/${commitSha}))
189+
174190
Previous issues have been resolved. Thank you for addressing the security concerns!
191+
175192
---
176193
*This comment will be updated if new secrets are detected in future commits.*
177194
`;
178-
await github.rest.issues.updateComment({
179-
owner: context.repo.owner,
180-
repo: context.repo.repo,
181-
comment_id: existing.id,
182-
body: body
183-
});
195+
await github.rest.issues.updateComment({
196+
owner: context.repo.owner,
197+
repo: context.repo.repo,
198+
comment_id: existing.id,
199+
body: body
200+
});
201+
}
202+
// If it was just a warning (unverified only), leave it as-is
184203
}
204+
// If no existing comment and no secrets, don't post anything
185205
return;
186206
}
187207
208+
// Secrets found - create or update warning comment
188209
let severity, icon, action;
189210
if (hasVerified) {
190211
severity = 'CRITICAL';
@@ -198,22 +219,29 @@ jobs:
198219
199220
body = `${commentMarker}
200221
## ${icon} Secret Scanning ${severity}
222+
201223
**TruffleHog scan results:**
202224
- **Verified (active) secrets:** ${verifiedCount} ${verifiedCount > 0 ? ':x:' : ':white_check_mark:'}
203225
- **Unverified (potential) secrets:** ${unverifiedCount} ${unverifiedCount > 0 ? ':warning:' : ':white_check_mark:'}
226+
204227
**Scanned commit:** \`${shortSha}\` ([${commitSha}](${{ github.server_url }}/${{ github.repository }}/commit/${commitSha}))
228+
205229
${action}
230+
206231
### What to do:
207232
1. **Review the workflow annotations** - they point to exact file and line locations
208233
2. **Remove any exposed secrets** from your code
209234
3. **Rotate compromised credentials** - especially verified ones
210235
4. **Push the fix** to this branch
236+
211237
### Understanding Results
212238
| Type | Meaning | Action Required |
213239
|------|---------|-----------------|
214240
| **Verified** | Confirmed active credential | **Must remove & rotate** - PR blocked |
215241
| **Unverified** | Potential secret pattern | Review recommended - PR can proceed |
242+
216243
Check the [workflow run logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details.
244+
217245
---
218246
*Verified secrets are confirmed active by TruffleHog. Unverified secrets match known patterns but couldn't be validated.*
219247
`;

0 commit comments

Comments
 (0)