Files
2025-11-29 17:51:02 +08:00

182 lines
5.8 KiB
YAML

# GitHub Actions Workflow for Gitleaks Secret Scanning
# Save as: .github/workflows/gitleaks.yml
name: Secret Scanning with Gitleaks
on:
push:
branches:
- main
- develop
- 'release/**'
pull_request:
branches:
- main
- develop
schedule:
# Run daily at 2 AM UTC
- cron: '0 2 * * *'
workflow_dispatch: # Allow manual triggers
# Cancel in-progress runs when new commit pushed
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
gitleaks-scan:
name: Scan for Secrets
runs-on: ubuntu-latest
permissions:
# Required for uploading SARIF results to GitHub Security tab
security-events: write
# Required for checking out private repos
contents: read
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
# Fetch full history for comprehensive scanning
fetch-depth: 0
- name: Run Gitleaks Scan
id: gitleaks
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Optional: Use custom configuration
# GITLEAKS_CONFIG: .gitleaks.toml
# Optional: Generate JSON report for further processing
- name: Generate JSON Report
if: always() # Run even if secrets found
run: |
docker run --rm -v ${{ github.workspace }}:/repo \
zricethezav/gitleaks:latest \
detect --source /repo \
--report-path /repo/gitleaks-report.json \
--report-format json \
--exit-code 0 || true
# Optional: Upload JSON report as artifact
- name: Upload Scan Report
if: always()
uses: actions/upload-artifact@v4
with:
name: gitleaks-report
path: gitleaks-report.json
retention-days: 30
# Optional: Generate SARIF report for GitHub Security tab
- name: Generate SARIF Report
if: always()
run: |
docker run --rm -v ${{ github.workspace }}:/repo \
zricethezav/gitleaks:latest \
detect --source /repo \
--report-path /repo/gitleaks.sarif \
--report-format sarif \
--exit-code 0 || true
# Optional: Upload SARIF report to GitHub Security
- name: Upload SARIF to GitHub Security
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: gitleaks.sarif
category: gitleaks
# Optional: Comment on PR with findings
- name: Comment PR with Findings
if: failure() && github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
try {
const report = JSON.parse(fs.readFileSync('gitleaks-report.json', 'utf8'));
const findings = report.length;
const comment = `## 🔒 Secret Scanning Results
⚠️ **${findings} potential secret(s) detected!**
Please review the findings and take immediate action:
1. **Do not merge** this PR until secrets are removed
2. Rotate any exposed credentials immediately
3. Remove secrets from code and use environment variables
4. Review the security tab for detailed findings
See [Secret Scanning Guide](https://github.com/${{ github.repository }}/blob/main/docs/secret-scanning.md) for remediation steps.`;
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: comment
});
} catch (error) {
console.log('No report file or error reading it:', error.message);
}
# Optional: Post to Slack on failure
- name: Notify Slack on Failure
if: failure()
uses: slackapi/slack-github-action@v1
with:
payload: |
{
"text": "🚨 Secrets detected in ${{ github.repository }}",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Secret Scanning Alert*\n\nSecrets detected in repository: `${{ github.repository }}`\nBranch: `${{ github.ref_name }}`\nCommit: `${{ github.sha }}`\n\n<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Details>"
}
}
]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
# Optional: Baseline scanning for incremental detection
baseline-scan:
name: Incremental Scan Against Baseline
runs-on: ubuntu-latest
if: github.event_name == 'push'
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download Existing Baseline
continue-on-error: true
run: |
# Download baseline from artifact storage or S3
# Example: aws s3 cp s3://bucket/.gitleaks-baseline.json .
echo "Baseline download would go here"
- name: Run Incremental Scan
run: |
docker run --rm -v ${{ github.workspace }}:/repo \
zricethezav/gitleaks:latest \
detect --source /repo \
--baseline-path /repo/.gitleaks-baseline.json \
--report-path /repo/new-findings.json \
--report-format json \
--exit-code 1 || true
- name: Upload New Findings
if: always()
uses: actions/upload-artifact@v4
with:
name: new-findings
path: new-findings.json
retention-days: 90