Skip to content
Open
Show file tree
Hide file tree
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
96 changes: 96 additions & 0 deletions .github/workflows/Gitleaks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
name: Gitleaks secrets scan

on:
pull_request:
branches:
- v2

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/Rule/gitleaks.toml" \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you check if this file can be sourced from a centralized location instead of creating a separate gitleaks.toml file in every repository?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For private repo's we have done the same. But for the public repo's, we are hosting the workflows separately, mainly for the SDK's, as we need to change the file or modify it often to reduce the False positives with respect to the individual repo's.

--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"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you create a separate script for this and execute it, instead of keeping the logic directly in the workflow file?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the existing logic, we are using the Git API and commenting it directly on the PR. This is the direct logic, even if we write any other script for the commenting we need to call the api's or the commenting git actions which needs all the same syntax.

Also for the separate script we need to again install the req functions to run that script which again consumes git runner resources.

65 changes: 47 additions & 18 deletions .github/workflows/semgrep.yml
Original file line number Diff line number Diff line change
@@ -1,35 +1,64 @@
name: Semgrep
name: Semgrep Scan

# Run workflow each time code is pushed to your repository.
on:
push:
branches:
- main
pull_request:
branches:
- main
- v2

jobs:
build:
runs-on: ubuntu-latest
permissions:
pull-requests: write # Give write permission to PRs
issues: write
steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Install Semgrep
run: pip install semgrep
- name: Install Semgrep and jq
run: |
sudo apt install python3-venv jq
python3 -m venv .venv
.venv/bin/pip install semgrep
- name: Run Semgrep
run: |
semgrep --config .semgreprules/customRule.yml --config auto --severity ERROR --sarif . > results.sarif
source .venv/bin/activate
semgrep --config auto --severity ERROR --json-output=results.json --no-error
cat results.json | jq .results > pretty-results.json
- name: Upload SARIF file
uses: github/codeql-action/upload-sarif@v3
- name: Display Raw Semgrep JSON Output
run: |
echo "Displaying raw Semgrep results..."
cat pretty-results.json
- name: Add comment on PR if findings are found
uses: actions/github-script@v6
with:
# Path to SARIF file relative to the root of the repository
sarif_file: results.sarif
script: |
// Ensure the context has a pull_request
if (context.payload.pull_request) {
const prNumber = context.payload.pull_request.number;
const fs = require('fs');
const results = JSON.parse(fs.readFileSync('pretty-results.json', 'utf8'));
const highFindings = results.filter(result => result.extra && result.extra.severity === 'ERROR');
- name: Upload results
uses: actions/upload-artifact@v4
with:
name: semgrep-results
path: results.sarif
// Comment if findings exist
if (highFindings.length > 0) {
const comment = `**Semgrep Findings:** Issues with Error level severity are found (Error is Highest severity in Semgrep), Please resolve the issues before merging.`;
await github.rest.issues.createComment({
...context.repo,
issue_number: prNumber,
body: comment
});
} else {
const noIssuesComment = "**Semgrep findings:** No issues found, Good to merge.";
await github.rest.issues.createComment({
...context.repo,
issue_number: prNumber,
body: noIssuesComment
});
}
} else {
console.log("This workflow wasn't triggered by a pull request, so no comment will be added.");
}
Comment on lines +38 to +64
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto same as above.

30 changes: 0 additions & 30 deletions .semgreprules/customRule.yml

This file was deleted.

Loading
Loading