name: Vulnerability Scan on: pull_request: push: branches: [main] schedule: # Run weekly on Monday at 9:00 UTC - cron: '0 9 * * 1' permissions: contents: read jobs: pip-audit: name: pip-audit runs-on: ubuntu-latest steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 with: persist-credentials: false - name: Restore global uv cache id: cache-restore uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: path: | ~/.cache/uv ~/.local/share/uv .venv key: uv-main-py3.11-${{ hashFiles('uv.lock') }} restore-keys: | uv-main-py3.11- - name: Install uv uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6 with: version: "0.11.3" python-version: "3.11" enable-cache: false - name: Install dependencies run: uv sync --all-groups --all-extras --no-install-project - name: Install pip-audit run: uv pip install pip-audit - name: Run pip-audit run: | pip_audit_args=( --desc --aliases --skip-editable --format json --output pip-audit-report.json --ignore-vuln CVE-2026-27448 # pyOpenSSL: fixes require 26.0.0, blocked by snowflake-connector-python 3.x. --ignore-vuln CVE-2026-27459 # pyOpenSSL: same constraint as CVE-2026-27448. --ignore-vuln PYSEC-2026-597 # nltk 3.9.4 (CVE-2026-12243): no fix available, transitive through crewai-tools[xml] -> unstructured. --ignore-vuln GHSA-rrmf-rvhw-rf47 # torch 2.12.0 (CVE-2025-3000): local-only memory corruption in torch.jit.script; no fix available. --ignore-vuln GHSA-f4j7-r4q5-qw2c # chromadb 1.1.1 (CVE-2026-45829): pre-auth RCE in the HTTP server; no fix available. --ignore-vuln GHSA-xf7x-x43h-rpqh # json-repair 0.25.3: the affected schema module is absent, and CrewAI does not pass schemas. ) uv run pip-audit "${pip_audit_args[@]}" continue-on-error: true - name: Display results if: always() run: | if [ -f pip-audit-report.json ]; then echo "## pip-audit Results" >> $GITHUB_STEP_SUMMARY echo '```json' >> $GITHUB_STEP_SUMMARY cat pip-audit-report.json | python3 -m json.tool >> $GITHUB_STEP_SUMMARY echo '```' >> $GITHUB_STEP_SUMMARY # Fail if vulnerabilities found python3 -c " import json, sys with open('pip-audit-report.json') as f: data = json.load(f) vulns = [d for d in data.get('dependencies', []) if d.get('vulns')] if vulns: print(f'::error::Found vulnerabilities in {len(vulns)} package(s)') for v in vulns: for vuln in v['vulns']: print(f' - {v[\"name\"]}=={v[\"version\"]}: {vuln[\"id\"]}') sys.exit(1) print('No known vulnerabilities found') " else echo "::error::pip-audit failed to produce a report. Check the pip-audit step logs." exit 1 fi - name: Upload pip-audit report if: always() uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: pip-audit-report path: pip-audit-report.json - name: Save uv caches if: steps.cache-restore.outputs.cache-hit != 'true' uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: path: | ~/.cache/uv ~/.local/share/uv .venv key: uv-main-py3.11-${{ hashFiles('uv.lock') }}