Skip to content

Centralized Secret Scanning Report #2

Centralized Secret Scanning Report

Centralized Secret Scanning Report #2

name: Secret Scanning Report Generator
on:
workflow_dispatch:
inputs:
include_inactive:
description: 'Include inactive alerts in report'
required: false
type: boolean
default: false
max_workers:
description: 'Maximum number of concurrent workers'
required: false
type: number
default: 10
log_level:
description: 'Logging level'
required: false
type: choice
options:
- INFO
- DEBUG
- WARNING
- ERROR
default: 'INFO'
schedule:
- cron: '0 0 * * 1' # Weekly on Monday at midnight
permissions:
security-events: read # Required for secret scanning API
contents: read # Required for checking out code
actions: write # Required for artifact upload
issues: write # Required for creating issues on failure
jobs:
generate-report:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11' # Updated to latest stable Python
cache: 'pip'
cache-dependency-path: requirements.txt
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Generate timestamp
id: timestamp
run: echo "timestamp=$(date +%Y%m%d_%H%M%S)" >> $GITHUB_OUTPUT
- name: Generate Secret Report
id: generate-report
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ORGANIZATION: ${{ github.repository_owner }}
REPORT_FILE: "secret_report_${{ steps.timestamp.outputs.timestamp }}.csv"
run: |
# Create output directory
mkdir -p reports
# Run the scanner with configured parameters
python ./scripts/github_secret_scanner.py \
--org "$ORGANIZATION" \
--token "$GITHUB_TOKEN" \
--output "reports/${REPORT_FILE}" \
--log-level ${{ inputs.log_level || 'INFO' }} \
--max-workers ${{ inputs.max_workers || 10 }} \
--max-retries 3 \
${{ inputs.include_inactive && '--include-inactive' || '' }}
# Save report path for later steps
echo "report_path=reports/${REPORT_FILE}" >> $GITHUB_OUTPUT
- name: Upload report
uses: actions/upload-artifact@v4
if: success()
with:
name: secret-scanning-report-${{ steps.timestamp.outputs.timestamp }}
path: ${{ steps.generate-report.outputs.report_path }}
retention-days: 30
if-no-files-found: error
- name: Process report statistics
if: success()
id: stats
run: |
total_alerts=$(python scripts/process_report.py --input ${{ steps.generate-report.outputs.report_path }} --count)
active_alerts=$(python scripts/process_report.py --input ${{ steps.generate-report.outputs.report_path }} --active)
echo "Total alerts found: $total_alerts"
echo "Active alerts: $active_alerts"
# Save stats for issue creation
echo "total_alerts=$total_alerts" >> $GITHUB_OUTPUT
echo "active_alerts=$active_alerts" >> $GITHUB_OUTPUT
- name: Create summary issue
if: success() && ${{ steps.stats.outputs.active_alerts > 10 }}
uses: actions/github-script@v7
with:
script: |
const stats = {
total: '${{ steps.stats.outputs.total_alerts }}',
active: '${{ steps.stats.outputs.active_alerts }}'
};
const body = `
# Secret Scanning Report Summary
Report generated on: ${new Date().toISOString()}
## Statistics
- Total alerts analyzed: ${stats.total}
- Active alerts found: ${stats.active}
## Details
- Report artifact: [Download report](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId})
- Workflow run: [View details](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId})
## Configuration
- Include inactive alerts: ${{ inputs.include_inactive || 'false' }}
- Max workers: ${{ inputs.max_workers || '10' }}
- Log level: ${{ inputs.log_level || 'INFO' }}
`;
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `📊 Secret Scanning Report - ${new Date().toISOString().split('T')[0]}`,
body: body,
labels: ['secret-scanning', 'report']
});
- name: Notify on failure
if: failure()
uses: actions/github-script@v7
with:
script: |
const body = `
# 🚨 Secret Scanning Report Generation Failed
Workflow run failed at ${new Date().toISOString()}
## Details
- Run ID: \`${context.runId}\`
- Trigger: ${context.eventName}
- Actor: @${context.actor}
## Links
- [View run details](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId})
- [View workflow file](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/blob/main/.github/workflows/secret-scanning-report.yml)
Please check the workflow logs for detailed error information.
`;
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: '🚨 Secret Scanning Report Generation Failed',
body: body,
labels: ['secret-scanning', 'failed']
});
- name: Clean up
if: always()
run: |
# Securely remove any sensitive files
if [ -d "reports" ]; then
find reports -type f -exec shred -u {} \;
rm -rf reports
fi
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true