Skip to content

chore(phase1): 100% Phase 1 Completion (Logs, Analysis, Docs) #47

chore(phase1): 100% Phase 1 Completion (Logs, Analysis, Docs)

chore(phase1): 100% Phase 1 Completion (Logs, Analysis, Docs) #47

Workflow file for this run

name: Security Scan
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
schedule:
# Run weekly to catch new vulnerabilities in pinned dependencies
- cron: '0 0 * * 0'
jobs:
security-audit:
runs-on: ubuntu-latest
permissions:
security-events: write # Required to upload SARIF to GitHub Security tab
contents: read
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 Security Tools
run: |
python -m pip install --upgrade pip
pip install "bandit[sarif]>=1.7" pip-audit
- name: Run Bandit (Python Static Security Scan)
# -r: recursive scan of src/
# -ll: report medium and above severity (high-confidence)
# Lines annotated with # nosec BXXX are intentionally excluded
# --format sarif: machine-readable output for GitHub Security tab
run: |
bandit -r src/ -ll --format sarif -o bandit-results.sarif || EXIT=$?
# Summarise findings in human-readable form too
bandit -r src/ -ll || true
# Propagate non-zero exit only if there are unannotated HIGH findings
if [ "${EXIT:-0}" -ne 0 ]; then
HIGH=$(python -c "
import json, sys
with open('bandit-results.sarif') as f:
sarif = json.load(f)
runs = sarif.get('runs', [])
high = sum(
1 for run in runs for result in run.get('results', [])
if result.get('properties', {}).get('issue_severity') == 'HIGH'
)
print(high)
")
echo "High-severity unannotated issues: $HIGH"
if [ "$HIGH" -gt 0 ]; then exit 1; fi
fi
- name: Upload Bandit SARIF to GitHub Security Tab
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: bandit-results.sarif
category: bandit
- name: Run pip-audit (Dependency Vulnerability Scan)
# Queries PyPI Advisory DB for known CVEs in pinned dependencies
run: |
pip-audit -r requirements.txt --format json -o pip-audit-report.json || true
pip-audit -r requirements.txt || true
- name: Upload Security Reports as Artifacts
uses: actions/upload-artifact@v4
if: always()
with:
name: security-reports
path: |
bandit-results.sarif
pip-audit-report.json
retention-days: 90