Skip to content

ci: security-deps workflow — pip-audit CVE gate on PRs#114

Merged
nelsonduarte merged 3 commits into
mainfrom
ci/python-deps-security-check
Jul 11, 2026
Merged

ci: security-deps workflow — pip-audit CVE gate on PRs#114
nelsonduarte merged 3 commits into
mainfrom
ci/python-deps-security-check

Conversation

@nelsonduarte

Copy link
Copy Markdown
Owner

Summary

Adds a CI workflow that runs pip-audit against requirements.txt and flatpak/requirements-pinned.txt on every PR that touches those files, plus weekly cron and manual dispatch. Fails the build if any known vulnerability is found (blocks merge). Also posts an informational comment on the PR summarizing findings + outdated packages.

Trigger

  • pull_request on changes to requirements.txt / flatpak/requirements-pinned.txt / workflow file
  • push to main on same paths
  • Weekly cron (Monday 06:00 UTC) — safety net for CVEs published without repo changes
  • Manual: gh workflow run security-deps.yml

Behavior

  • Blocking: final pip-audit --strict step fails on any vulnerability → merge blocked
  • Informational: pip-audit markdown, outdated-packages report (comment on PR, non-blocking)
  • Fork safety: comment step has continue-on-error: true so the strict gate runs even when the token is read-only on fork PRs

Files

  • .github/workflows/security-deps.yml (new, 205 lines) — workflow itself
  • tests/test_security_deps_workflow.py (new, 12 tests) — regression coverage
  • CONTRIBUTING.md (+18 lines) — user-facing docs

Actions pinned

Uses only official actions/* (no third-party marketplace deps in a security workflow):

  • actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 (v7.0.0)
  • actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 (v6.3.0)

Both SHAs match the pinning already used in build.yml / codeql.yml / publish.yml / release.yml for consistency.

pip-audit itself pinned to ==2.10.1 inside the workflow to avoid a race with a future pip-audit release changing exit-code semantics.

PR comment via gh CLI

No third-party comment action. Uses gh api to find an existing comment by section-heading marker, then gh api ... -X PATCH to update it (or gh pr comment to create). Avoids marketplace supply chain surface for a workflow explicitly guarding against supply-chain risk.

Adversarial review

Review found and fixed:

  • F1 blocker: fork PRs have read-only GITHUB_TOKEN regardless of declared pull-requests: write. Comment step failed with 403 → strict gate skipped by default if: success(). Fixed by adding continue-on-error: true to the comment step so the gate always runs. New regression test enforces this.
  • Bonus: pinned pip-audit to a specific version.

Complements Dependabot

  • Dependabot: proactive — opens PRs when a package update is available.
  • security-deps: reactive — fails any PR (including feature branches) that introduces a CVE via transitive dep that Dependabot won't touch.

Also catches CVEs in transitives outside requirements.txt (urllib3, certifi, etc.) if they surface through pip-audit.

Validation

  • 3 atomic commits
  • pytest tests/test_security_deps_workflow.py → 12 passed
  • YAML validated with yaml.safe_load
  • Ruff clean on the new test file
  • Bandit clean on the workflow file
  • No APP_VERSION bump
  • No new dependencies in requirements.txt

After merge

The workflow starts running on the next PR that touches requirements.txt. Weekly cron picks up CVEs published without repo changes.

Runs pip-audit against requirements.txt and flatpak/requirements-pinned.txt
on every PR that touches those files, plus weekly cron as safety net.

- Fails the build if any known CVE is found (blocks merge via pip-audit --strict)
- Posts an informational summary comment on the PR (updates existing comment
  rather than piling up new ones on every push)
- Includes an outdated-packages report against PyPI (non-blocking)
- Uses gh CLI for PR comment (no third-party action dependency in a
  security workflow)

Manual dispatch supported via `gh workflow run security-deps.yml`.
Documents the automated pip-audit gate that now runs on every PR,
so contributors know why an outdated pin can block their merge and
how to trigger the workflow manually.
Round 11 review caught that fork PRs have GITHUB_TOKEN read-only
regardless of declared permissions, so `gh api PATCH` / `gh pr comment`
returns 403 -> comment step fails -> strict gate is skipped by default
`if: success()`. The workflow marks itself as failed, but the CVE gate
never runs, giving a false signal to reviewers.

Adds `continue-on-error: true` to the comment step so the strict gate
runs regardless. Comment failure is acceptable on fork PRs — users
see the CI check status instead.

Also pins pip-audit to 2.10.1 so an upstream regression cannot silently
break the security gate, and adds a regression test that verifies
continue-on-error is present on the comment step.
@github-actions

Copy link
Copy Markdown
Contributor

Python dependencies security check

pip-audit: requirements.txt

No known vulnerabilities.

pip-audit: flatpak/requirements-pinned.txt

No known vulnerabilities.

Outdated check (informational)

Package Pin Latest on PyPI Status
PySide6 PySide6>=6.11.1 6.11.1 up-to-date
pypdf pypdf>=6.14.2 6.14.2 up-to-date
cryptography cryptography>=49.0.0 49.0.0 up-to-date
qtawesome qtawesome>=1.4.1 1.4.2 outdated
pillow pillow>=12.1.1 12.3.0 outdated
pymupdf pymupdf>=1.27.2.3 1.28.0 outdated
pytesseract pytesseract>=0.3.13 0.3.13 up-to-date
python-docx python-docx>=1.2.0 1.2.0 up-to-date
python-pptx python-pptx>=1.0.2 1.0.2 up-to-date
openpyxl openpyxl>=3.1.5 3.1.5 up-to-date
beautifulsoup4 beautifulsoup4>=4.15.0 4.15.0 up-to-date
ebooklib ebooklib>=0.20 0.20 up-to-date
lxml lxml>=6.1.1 6.1.1 up-to-date
urllib3 urllib3>=2.7.0 2.7.0 up-to-date
idna idna>=3.18 3.18 up-to-date
pyinstaller pyinstaller>=6.21.0 6.21.0 up-to-date

Auto-generated by security-deps workflow. Merge is blocked only when pip-audit --strict reports vulnerabilities.

@nelsonduarte nelsonduarte merged commit 59c6304 into main Jul 11, 2026
5 checks passed
@nelsonduarte nelsonduarte deleted the ci/python-deps-security-check branch July 11, 2026 10:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant