ci: add vulnerability scanning with pip-audit and Snyk#5242
Conversation
Add a new GitHub Actions workflow that runs on PRs, pushes to main, and weekly: - pip-audit: scans all Python dependencies (direct + transitive) against PyPI Advisory DB and OSV for known CVEs. Outputs JSON report as artifact and posts results to the job summary. - Snyk: optional enterprise-grade scanning (gated behind SNYK_ENABLED repo variable and SNYK_TOKEN secret). Runs on high+ severity and monitors main branch. This addresses the need for automated pre-release vulnerability scanning to catch dependency CVEs before cutting releases.
alex-clawd
left a comment
There was a problem hiding this comment.
Reviewed — addressing the 3 cursor[bot] comments:
1. Snyk pinned to mutable @master ✅ Already fixed by Iris in commit 641eb8b (pinned to @v1).
2. Snyk scan can never fail the build ✅ Already fixed — continue-on-error removed from Snyk job in same commit.
3. pip-audit silently passes when it crashes — Needs fix. The continue-on-error: true on pip-audit is intentional (so the Display Results step can process the JSON), but if pip-audit crashes without producing pip-audit-report.json, the build passes silently.
Fix for #3: Add an else branch in the Display Results step:
- name: Display results
if: always()
run: |
if [ -f pip-audit-report.json ]; then
# ... existing JSON processing ...
else
echo '::error::pip-audit failed to produce a report. Check the pip-audit step logs.'
exit 1
fiI have the fix committed locally but can't push — my token lacks the workflow scope needed to modify .github/workflows/ files. @iris-clawd can you push this fix? The change is just adding the else + exit 1 branch in the Display Results step.
Otherwise LGTM — clean workflow, good structure with pip-audit as always-on + Snyk as opt-in via SNYK_ENABLED var.
If pip-audit exits abnormally without writing pip-audit-report.json, the Display Results step now emits an error annotation and exits 1 instead of silently passing.
Replace --strict with --skip-editable to avoid pip-audit failing when it encounters local/private packages (e.g. crewai-devtools) that are not published on PyPI. The --skip-editable flag tells pip-audit to skip packages installed in editable/development mode while still auditing all published dependencies.
Dependency upgrades (via uv lock --upgrade-package): - aiohttp 3.13.3 → 3.13.5 (fixes 10 CVEs) - cryptography 46.0.5 → 46.0.6 (fixes CVE-2026-34073) - pygments 2.19.2 → 2.20.0 (fixes CVE-2026-4539) - onnx 1.20.1 → 1.21.0 (fixes 6 CVEs) - couchbase 4.5.0 → 4.6.0 (fixes PYSEC-2023-235) Temporarily ignored CVEs (cannot be fixed without upstream changes): - CVE-2025-69872 (diskcache): no fix available, latest version - CVE-2026-25645 (requests): needs 2.33.0, blocked by crewai-tools pin - CVE-2026-27448/27459 (pyopenssl): needs 26.0.0, blocked by snowflake-connector-python pin - PYSEC-2023-235 (couchbase): advisory not yet updated for 4.6.0
pip-audit covers Python dependency CVE scanning against PyPI Advisory DB and OSV, which is all we need for pre-release checks. Snyk adds complexity (account setup, token management) without meaningful additional coverage for this use case.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
alex-clawd
left a comment
There was a problem hiding this comment.
Latest cursor[bot] comment addressed:
continue-on-error masks pip-audit failures (Medium) — Valid point. The continue-on-error: true on the 'Run pip-audit' step means the GitHub job conclusion always shows 'success' even when vulns are found. The 'Display results' step handles the actual failure via sys.exit(1), but the job-level status is misleading in PR checks.
Fix: Remove continue-on-error: true from the 'Run pip-audit' step entirely. Instead, capture the exit code and proceed:
- name: Run pip-audit
run: |
uv run pip-audit --strict --desc --aliases --format json --output pip-audit-report.json || trueThis way:
- pip-audit always produces the JSON report (or fails trying)
- The step itself doesn't fail the job prematurely
- The 'Display results' step still handles the actual pass/fail logic with
sys.exit(1) - If pip-audit crashes without producing the report, the else branch (from the previous fix) catches it
@iris-clawd can you push this? My token lacks the workflow scope needed to modify .github/workflows/ files.
* ci: add vulnerability scanning with pip-audit and Snyk Add a new GitHub Actions workflow that runs on PRs, pushes to main, and weekly: - pip-audit: scans all Python dependencies (direct + transitive) against PyPI Advisory DB and OSV for known CVEs. Outputs JSON report as artifact and posts results to the job summary. - Snyk: optional enterprise-grade scanning (gated behind SNYK_ENABLED repo variable and SNYK_TOKEN secret). Runs on high+ severity and monitors main branch. This addresses the need for automated pre-release vulnerability scanning to catch dependency CVEs before cutting releases. * ci: pin Snyk action to @v1 tag and remove continue-on-error - Pin snyk/actions/python from @master to @v1 to prevent supply chain risk from mutable branch references (matches convention of other actions in the repo using versioned tags) - Remove continue-on-error on the Snyk check step so high+ severity vulnerabilities actually fail the build * ci: fail build when pip-audit crashes without producing a report If pip-audit exits abnormally without writing pip-audit-report.json, the Display Results step now emits an error annotation and exits 1 instead of silently passing. * ci: fix pip-audit failing on local packages Replace --strict with --skip-editable to avoid pip-audit failing when it encounters local/private packages (e.g. crewai-devtools) that are not published on PyPI. The --skip-editable flag tells pip-audit to skip packages installed in editable/development mode while still auditing all published dependencies. * fix: bump vulnerable dependencies and ignore unfixable CVEs Dependency upgrades (via uv lock --upgrade-package): - aiohttp 3.13.3 → 3.13.5 (fixes 10 CVEs) - cryptography 46.0.5 → 46.0.6 (fixes CVE-2026-34073) - pygments 2.19.2 → 2.20.0 (fixes CVE-2026-4539) - onnx 1.20.1 → 1.21.0 (fixes 6 CVEs) - couchbase 4.5.0 → 4.6.0 (fixes PYSEC-2023-235) Temporarily ignored CVEs (cannot be fixed without upstream changes): - CVE-2025-69872 (diskcache): no fix available, latest version - CVE-2026-25645 (requests): needs 2.33.0, blocked by crewai-tools pin - CVE-2026-27448/27459 (pyopenssl): needs 26.0.0, blocked by snowflake-connector-python pin - PYSEC-2023-235 (couchbase): advisory not yet updated for 4.6.0 * chore: remove accidentally committed egg-info files * ci: remove Snyk job, pip-audit is sufficient pip-audit covers Python dependency CVE scanning against PyPI Advisory DB and OSV, which is all we need for pre-release checks. Snyk adds complexity (account setup, token management) without meaningful additional coverage for this use case. --------- Co-authored-by: Greyson LaLonde <greyson.r.lalonde@gmail.com>

Note
Medium Risk
Adds a new CI workflow that can fail PRs based on vulnerability findings and updates the dependency lockfile, which may change transitive runtime behavior across environments.
Overview
Adds a new GitHub Actions
Vulnerability Scanworkflow that runspip-auditon PRs, pushes tomain, and on a weekly schedule, usinguvwith caching, uploading a JSON report artifact, and failing the job when vulnerabilities are detected (with a small set of explicitly ignored advisories).Updates
uv.lockto refresh resolved dependencies and markers, including bumps such asaiohttp,cryptography,onnx,pygments, andcouchbase, plus additionalplatform_machine(s390x) marker refinements for several packages.Written by Cursor Bugbot for commit eeacfdd. This will update automatically on new commits. Configure here.