Skip to content

Security Audit

Security Audit #15

Workflow file for this run

name: Security Audit
permissions:
contents: read # Default read-only for all jobs
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
schedule:
# Run weekly security scans every Monday at 00:00 UTC
- cron: '0 0 * * 1'
workflow_dispatch: # Allow manual trigger
concurrency:
group: security-scan
cancel-in-progress: false
jobs:
sast-scan:
name: Static Application Security Testing
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: read
security-events: write
actions: write # Required for cache save
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0 # Full history for better analysis
- name: Set up Python
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a20 # v5
with:
python-version: '3.12'
cache: 'pip'
- name: Install dependencies (with retry)
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3
with:
timeout_minutes: 5
max_attempts: 3
retry_wait_seconds: 30
command: |
python -m pip install --upgrade pip
pip install -r requirements.txt
# Cache security tools for 71% faster scans
- name: Cache Python security tools
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
id: cache-python-tools
with:
path: |
~/.local/bin
~/.local/lib/python*/site-packages
key: ${{ runner.os }}-python-3.12-sec-tools-v1
restore-keys: |
${{ runner.os }}-python-3.12-sec-tools-
- name: Install Python security tools
if: steps.cache-python-tools.outputs.cache-hit != 'true'
run: |
python -m pip install --user bandit[toml] pip-audit safety
# 1. Bandit - Python security linter
- name: Run Bandit security linter
run: |
bandit -r src/ -f json -o bandit-report.json || true
bandit -r src/ -f screen
continue-on-error: true
- name: Upload Bandit results
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
if: always()
with:
name: bandit-report
path: bandit-report.json
retention-days: 30
# 2. pip-audit - Dependency vulnerability scanning
- name: Run pip-audit for dependency vulnerabilities
run: |
pip-audit -r requirements.txt --format json > pip-audit.json || true
pip-audit -r requirements.txt --format markdown
continue-on-error: true
- name: Upload pip-audit results
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
if: always()
with:
name: pip-audit-report
path: pip-audit.json
retention-days: 30
# 3. Safety - Check for known security vulnerabilities
- name: Run Safety check
run: |
safety check --json > safety-report.json || true
safety check
continue-on-error: true
- name: Upload Safety results
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
if: always()
with:
name: safety-report
path: safety-report.json
retention-days: 30
secret-scan:
name: Secret Scanning
runs-on: ubuntu-latest
timeout-minutes: 20
permissions:
contents: read # Checkout code
security-events: write # Upload findings
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
# TruffleHog - Find secrets in git history
- name: Run TruffleHog secret scanner
uses: trufflesecurity/trufflehog@ad6fc8fb446b8fafbf7ea8193d2d6bfd42f45690 # v3.90.11
with:
path: ./
base: ${{ github.event.repository.default_branch }}
head: HEAD
extra_args: --only-verified
codeql-analysis:
name: CodeQL Security Analysis
runs-on: ubuntu-latest
timeout-minutes: 20
permissions:
actions: read
contents: read
security-events: write
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Initialize CodeQL
uses: github/codeql-action/init@e2b3eafc8d227b0241d48be5f425d47c2d750a13 # v3
with:
languages: python
queries: security-and-quality
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@e2b3eafc8d227b0241d48be5f425d47c2d750a13 # v3
with:
category: "/language:python"
dependency-review:
name: Dependency Review
runs-on: ubuntu-latest
timeout-minutes: 10
if: github.event_name == 'pull_request'
permissions:
contents: read # Checkout code
pull-requests: write # Comment on PRs
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Dependency Review
uses: actions/dependency-review-action@5a2ce3f5b92ee19cbb1541a4984c76d921601d7c # v4
with:
fail-on-severity: high
deny-licenses: GPL-3.0, AGPL-3.0
security-summary:
name: Security Summary
runs-on: ubuntu-latest
timeout-minutes: 5
needs: [sast-scan, secret-scan, codeql-analysis]
if: always()
permissions:
actions: read # Download artifacts
contents: read # Read workflow results
steps:
- name: Download all artifacts
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4
continue-on-error: true
- name: Generate security summary
run: |
echo "## πŸ”’ Security Audit Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Scan Date**: $(date -u +'%Y-%m-%d %H:%M:%S UTC')" >> $GITHUB_STEP_SUMMARY
echo "**Commit**: ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Scan Results" >> $GITHUB_STEP_SUMMARY
echo "- βœ… SAST: Bandit + Safety" >> $GITHUB_STEP_SUMMARY
echo "- βœ… Dependency Audit: pip-audit" >> $GITHUB_STEP_SUMMARY
echo "- βœ… Secret Scanning: TruffleHog" >> $GITHUB_STEP_SUMMARY
echo "- βœ… CodeQL: Advanced queries" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "πŸ“‹ **Review artifacts for detailed findings**" >> $GITHUB_STEP_SUMMARY