Leaked Secrets Scan #36
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Leaked Secrets Scan | |
| on: | |
| workflow_call: | |
| schedule: | |
| - cron: '0 3 * * *' # Daily at 3 AM UTC (3-4 AM UK time) | |
| workflow_dispatch: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| jobs: | |
| secrets-scan: | |
| runs-on: ubuntu-latest | |
| name: ${{ github.event_name == 'schedule' && 'Scheduled Secrets Scan' || 'Secrets Scan' }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.12' | |
| cache: 'pip' | |
| - name: Install detect-secrets | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install detect-secrets | |
| - name: Verify baseline exists | |
| run: | | |
| if [ ! -f .secrets.baseline ]; then | |
| echo "::error::.secrets.baseline not found!" | |
| exit 1 | |
| fi | |
| echo "Found .secrets.baseline" | |
| - name: Scan for secrets | |
| run: | | |
| echo "Scanning for secrets..." | |
| detect-secrets scan \ | |
| --baseline .secrets.baseline \ | |
| --exclude-files '.*\.lock$' \ | |
| --exclude-files '.*migrations/versions/.*\.py$' \ | |
| --force-use-all-plugins | |
| - name: Audit baseline for unaudited secrets | |
| run: | | |
| echo "Auditing secrets baseline..." | |
| if grep -q '"is_secret": null' .secrets.baseline; then | |
| echo "::error::Found unaudited secrets in baseline! Run: detect-secrets audit .secrets.baseline" | |
| detect-secrets audit .secrets.baseline --report | |
| exit 1 | |
| fi | |
| echo "All secrets in baseline have been audited" | |
| detect-secrets audit .secrets.baseline --report | |
| - name: Check for new secrets in PR | |
| if: github.event_name == 'pull_request' | |
| run: | | |
| echo "Checking for new secrets in PR..." | |
| mkdir -p /tmp/pr-scan | |
| git diff origin/main...HEAD --name-only | while read -r file; do | |
| if [ -f "$file" ]; then | |
| mkdir -p "/tmp/pr-scan/$(dirname "$file")" 2>/dev/null || true | |
| cp "$file" "/tmp/pr-scan/$file" 2>/dev/null || true | |
| fi | |
| done | |
| if [ "$(ls -A /tmp/pr-scan 2>/dev/null)" ]; then | |
| echo "Scanning changed files..." | |
| detect-secrets scan \ | |
| --baseline .secrets.baseline \ | |
| --exclude-files '.*\.lock$' \ | |
| --exclude-files '.*migrations/versions/.*\.py$' \ | |
| --force-use-all-plugins \ | |
| /tmp/pr-scan || echo "No new secrets found" | |
| else | |
| echo "No files to scan" | |
| fi | |
| - name: Full repository scan (scheduled) | |
| if: github.event_name == 'schedule' | |
| run: | | |
| echo "Performing full repository scan..." | |
| detect-secrets scan \ | |
| --exclude-files '.*\.lock$' \ | |
| --exclude-files '.*migrations/versions/.*\.py$' \ | |
| --force-use-all-plugins | |
| - name: Upload baseline on failure | |
| uses: actions/upload-artifact@v6 | |
| if: failure() | |
| with: | |
| name: secrets-scan-results | |
| path: .secrets.baseline | |
| retention-days: 30 |