Skip to content

chore(deps): sync requirements.txt lock hashes with updated requireme… #236

chore(deps): sync requirements.txt lock hashes with updated requireme…

chore(deps): sync requirements.txt lock hashes with updated requireme… #236

Workflow file for this run

name: Security Scan
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
schedule:
# Weekly Monday 06:00 UTC sweep: catches CVEs newly disclosed against
# already-pinned dependencies that PR-triggered scans would never re-check.
- cron: '0 6 * * 1'
permissions: read-all
jobs:
bandit:
name: Bandit Security Scan
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.11'
- name: Install Bandit
run: pip install --require-hashes -r environments/requirements-security.txt
- name: Run Bandit
# Scans recursively, skipping tests and virtual environment directories.
# Gate fails on MEDIUM+ severity findings (-ll); low-severity style findings
# (e.g. subprocess use in dev scripts, asserts, try/except/pass) are reported
# by CodeQL/Semgrep but do not block the release per OpenSSF guidance.
run: bandit -r . -ll -x ./tests/,./.ci_test_venv/,./.venv/,./build/
secret-pattern-scan:
name: Custom Secret Pattern Scan
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.11'
- name: Scan for credential-like patterns
# Blocking gate: exits 1 if any high-entropy credential-like assignment
# is found in tracked source files. No external dependencies - pure stdlib.
run: python scripts/check_secrets.py
codeql:
name: CodeQL Static Analysis
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
steps:
- name: Checkout code
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- name: Initialize CodeQL
uses: github/codeql-action/init@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
with:
languages: python
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
semgrep:
name: Semgrep Security Scan (advisory)
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
steps:
- name: Checkout code
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.11'
- name: Install Semgrep
# Hash-pinned (OpenSSF Scorecard Pinned-Dependencies). Regenerate with:
# pip-compile --generate-hashes environments/requirements-semgrep.in
run: pip install --require-hashes -r environments/requirements-semgrep.txt
# Advisory gate (OpenSSF tier: non-blocking). `semgrep scan` exits non-zero
# on any finding, so without continue-on-error this step silently blocked
# merges. Findings are surfaced as tracked, dismissable alerts in the
# Security ▸ Code scanning tab via the SARIF upload below instead.
- name: Run Semgrep
continue-on-error: true
run: semgrep scan --config p/python --sarif --output semgrep.sarif
- name: Upload Semgrep SARIF
if: always()
uses: github/codeql-action/upload-sarif@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
with:
sarif_file: semgrep.sarif
category: semgrep
pip-audit:
name: pip-audit Dependency Scan (advisory)
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.11'
- name: Install pip-audit
# Hash-pinned (OpenSSF Scorecard Pinned-Dependencies). Regenerate with:
# pip-compile --generate-hashes environments/requirements-pip-audit.in
run: pip install --require-hashes -r environments/requirements-pip-audit.txt
# Advisory gate (OpenSSF tier: non-blocking). Audits the fully-pinned
# lockfile (--no-deps: trust the resolved set, do not re-resolve). Dependabot
# already tracks these in the Security tab; this surfaces them inline in CI
# and on the run summary so they are visible without leaving the PR.
#
# Risk-accepted advisories are suppressed here with verified IDs and logged
# in SECURITY.md's Risk-Acceptance Register. To accept a new one, add its
# ID below with a comment and a matching register entry - never suppress
# without one. PYSEC ids are matched by pip-audit's PyPI source; GHSA ids
# are kept alongside for traceability with Dependabot/Security-tab reports.
- name: Audit pinned lockfile
continue-on-error: true
run: |
pip-audit \
-r environments/requirements.lock \
--no-deps \
--desc \
--ignore-vuln PYSEC-2025-194 \
--ignore-vuln GHSA-rrmf-rvhw-rf47
# ^ CVE-2025-3000 (torch.jit.script) - no upstream patch; torch.jit.script
# is never called in SESTRAV. Risk-accepted, see SECURITY.md register.
- name: Write triage digest to run summary
if: always()
continue-on-error: true
run: |
{
echo "## pip-audit - environments/requirements.lock"
echo ""
pip-audit -r environments/requirements.lock --no-deps --format markdown \
--ignore-vuln PYSEC-2025-194 --ignore-vuln GHSA-rrmf-rvhw-rf47 || true
} >> "$GITHUB_STEP_SUMMARY"