Files
crewAI/.github/workflows/vulnerability-scan.yml
iris-clawd 931f3556cf
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Build uv cache / build-cache (3.10) (push) Has been cancelled
Build uv cache / build-cache (3.11) (push) Has been cancelled
Build uv cache / build-cache (3.12) (push) Has been cancelled
Build uv cache / build-cache (3.13) (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
ci: add vulnerability scanning with pip-audit and Snyk (#5242)
* 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>
2026-04-03 01:44:44 -03:00

106 lines
3.3 KiB
YAML

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@v4
- name: Restore global uv cache
id: cache-restore
uses: actions/cache/restore@v4
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@v6
with:
version: "0.8.4"
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: |
uv run pip-audit --desc --aliases --skip-editable --format json --output pip-audit-report.json \
--ignore-vuln CVE-2025-69872 \
--ignore-vuln CVE-2026-25645 \
--ignore-vuln CVE-2026-27448 \
--ignore-vuln CVE-2026-27459 \
--ignore-vuln PYSEC-2023-235
# Ignored CVEs:
# CVE-2025-69872 - diskcache 5.6.3: no fix available (latest version)
# CVE-2026-25645 - requests 2.32.5: fix requires 2.33.0, blocked by crewai-tools ~=2.32.5 pin
# CVE-2026-27448 - pyopenssl 25.3.0: fix requires 26.0.0, blocked by snowflake-connector-python <26.0.0 pin
# CVE-2026-27459 - pyopenssl 25.3.0: same as above
# PYSEC-2023-235 - couchbase: fixed in 4.6.0 (already upgraded), advisory not yet updated
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@v4
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@v4
with:
path: |
~/.cache/uv
~/.local/share/uv
.venv
key: uv-main-py3.11-${{ hashFiles('uv.lock') }}