Skip to content

Security Audit

Security Audit #9

name: Security Audit
on:
push:
branches: [ main, master, develop ]
pull_request:
branches: [ main, master ]
schedule:
# Run weekly on Monday at 00:00 UTC
- cron: '0 0 * * 1'
workflow_dispatch: # Allow manual trigger
jobs:
dependency-scan:
name: Dependency Vulnerability Scan
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
cache: 'pip'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install safety bandit
pip install -r requirements.txt
- name: Run Safety check
continue-on-error: true
run: |
safety check --json --output safety-report.json || true
echo "::group::Safety Report"
cat safety-report.json
echo "::endgroup::"
- name: Run Bandit security scan
continue-on-error: true
run: |
bandit -r src/ -f json -o bandit-report.json -ll || true
echo "::group::Bandit Report"
cat bandit-report.json
echo "::endgroup::"
- name: Upload security reports
uses: actions/upload-artifact@v4
if: always()
with:
name: security-reports
path: |
safety-report.json
bandit-report.json
retention-days: 30
- name: Check for critical vulnerabilities
run: |
# Check Safety report for critical/high vulnerabilities
if [ -f safety-report.json ]; then
CRITICAL=$(jq '[.vulnerabilities[] | select(.severity == "critical" or .severity == "high")] | length' safety-report.json 2>/dev/null || echo "0")
if [ "$CRITICAL" -gt 0 ]; then
echo "::error::Found $CRITICAL critical/high vulnerabilities!"
echo "::notice::Please review safety-report.json in artifacts"
exit 1
else
echo "::notice::No critical vulnerabilities found"
fi
fi
code-quality:
name: Code Quality & Security Patterns
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Install linting tools
run: |
python -m pip install --upgrade pip
pip install flake8 pylint mypy
- name: Run Flake8 linting
continue-on-error: true
run: |
flake8 src/ tests/ --count --select=E9,F63,F7,F82 --show-source --statistics
flake8 src/ tests/ --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Run type checking
continue-on-error: true
run: |
mypy src/ --ignore-missing-imports --no-strict-optional || true
secrets-scan:
name: Secrets Detection
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history needed for secrets scan
- name: Run Gitleaks
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }} # Optional: for Gitleaks Pro
dependency-review:
name: Dependency Review
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Dependency Review
uses: actions/dependency-review-action@v4
with:
fail-on-severity: moderate
deny-licenses: GPL-3.0, AGPL-3.0
security-summary:
name: Security Summary
runs-on: ubuntu-latest
needs: [dependency-scan, code-quality, secrets-scan]
if: always()
steps:
- name: Generate Summary
run: |
echo "# Security Audit Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "## Scan Results" >> $GITHUB_STEP_SUMMARY
echo "- Dependency Scan: ${{ needs.dependency-scan.result }}" >> $GITHUB_STEP_SUMMARY
echo "- Code Quality: ${{ needs.code-quality.result }}" >> $GITHUB_STEP_SUMMARY
echo "- Secrets Scan: ${{ needs.secrets-scan.result }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Review detailed reports in workflow artifacts." >> $GITHUB_STEP_SUMMARY