ci: add dependency audit workflow#3138
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a dedicated GitHub Actions “Security Audit” workflow to run deterministic pip-audit checks on PRs/push/manual runs (using a committed, hashed requirements snapshot) and a scheduled job that resolves/audits dependencies live across the supported OS/Python matrix. It also introduces a sync-gate script and corresponding tests/docs to keep the committed snapshot aligned with pyproject.toml.
Changes:
- Added
.github/workflows/security.ymlwith split triggers: deterministic audit for PR/push/manual + scheduled live-resolution audit matrix. - Added
.github/scripts/check_security_requirements.pyand a committed hashed requirements snapshot to gate PRs when dependency inputs change without regenerating the snapshot. - Added tests + CONTRIBUTING docs to enforce and document the workflow, pins, and local commands.
Show a summary per file
| File | Description |
|---|---|
.github/workflows/security.yml |
New Security Audit workflow with deterministic and scheduled dependency-audit jobs. |
.github/scripts/check_security_requirements.py |
Sync-gate script to detect dependency input changes and verify the committed snapshot is current. |
.github/security-audit-requirements.txt |
Committed hashed requirements snapshot used for deterministic audits. |
tests/test_security_workflow.py |
Static tests guarding workflow triggers, pins, matrix, and sync-gate behavior. |
CONTRIBUTING.md |
Documentation for local security audit and snapshot refresh commands. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 5/5 changed files
- Comments generated: 2
| - name: Checkout | ||
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | ||
| with: | ||
| fetch-depth: 2 | ||
|
|
| def main() -> int: | ||
| if not _dependency_inputs_changed(): | ||
| return 0 | ||
|
|
||
| generated_requirements = Path(os.environ["GENERATED_REQUIREMENTS"]) | ||
| generated_requirements.parent.mkdir(parents=True, exist_ok=True) |
mnriem
left a comment
There was a problem hiding this comment.
Please address Copilot feedback
ea424f9 to
e32404e
Compare
| - name: Set up Python | ||
| uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 | ||
| with: |
| - name: Set up Python ${{ matrix.python-version }} | ||
| uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 | ||
| with: | ||
| python-version: ${{ matrix.python-version }} |
|
Please address Copilot feedback |
mnriem
left a comment
There was a problem hiding this comment.
Please address Security Audit workflow
Add a Security Audit workflow with a dependency-audit job. Push/PR/manual runs pip-audit against a committed --generate-hashes requirements snapshot (.github/security-audit-requirements.txt) for deterministic CI, while the weekly scheduled run resolves the runtime + test dependency set live across the supported Python/OS matrix to surface newly published advisories. A sync gate (.github/scripts/check_security_requirements.py) fails PRs whose dependency inputs changed without refreshing the committed snapshot, so the committed file can't silently drift from pyproject.toml. Assisted-by: Codex (model: GPT-5, autonomous)
Assisted-by: Codex (model: GPT-5, autonomous)
Assisted-by: Codex (model: GPT-5, autonomous)
Assisted-by: Codex (model: GPT-5, autonomous)
Assisted-by: Codex (model: GPT-5, autonomous)
0e5ee97 to
6c6ab78
Compare
Security audit review summaryAudit feedback addressed
Failed check resolutionThe previous Dependency audit failure was caused by a genuinely stale committed requirements snapshot. It has been regenerated from current Validation
Head commit: 6c6ab78 Posted on behalf of @PascalThuet by Codex (model: GPT-5, autonomous). |
|
One maintenance-policy question surfaced while rebasing this PR: pyproject.toml still declares Python >=3.11, while the functional CI matrix currently tests only Python 3.13 and 3.14. The scheduled security audit covers 3.11 through 3.14. Could you confirm whether Python 3.11 and 3.12 remain officially supported, or are merely installable without CI guarantees? Depending on the intended policy, we could either retain 3.11–3.14 in the scheduled audit or align it with the functional CI matrix. Separately, the rebase exposed version drift for pinned actions between workflows (setup-uv v8.2.0 versus the repository-standard v8.3.2). This PR now aligns them, but a shared consistency check or documented convention could prevent future drift |
| uvx --from pip-audit==2.10.0 pip-audit --disable-pip --require-hashes -r .github/security-audit-requirements.txt --progress-spinner off | ||
| ``` | ||
|
|
||
| Run this before changing dependency metadata. Pull request, push, and manual CI audits use the committed hashed requirements file so they stay deterministic. The scheduled CI audit also resolves the runtime and `test` extra dependency set across the supported Python and OS matrix to catch newly published advisories. If dependency metadata changes, refresh the committed audit input before running pip-audit: |
Assisted-by: Codex (model: GPT-5, autonomous)
|
Addressed the latest Copilot review round. The contributor guidance now explicitly describes the Validation: 17 security/workflow tests passed; the snapshot sync gate passed; Commit: Posted on behalf of @PascalThuet by Codex (model: GPT-5, autonomous). |
Part of splitting #2442 into smaller, dedicated PRs. Rebased onto current
main.What
pip-audit --require-hashes.Security review feedback
The audit feedback is covered by the current branch:
GENERATED_REQUIREMENTSvalue produces an explicit error;actions/setup-pythonmatches the repository-standard pinned SHA;astral-sh/setup-uvnow also matches the repository-standard pinned SHA;The existing review threads are outdated; they were intentionally left for the reviewer or PR author to resolve.
Failed workflow root cause
The previous
Dependency auditcheck correctly detected that the committed requirements snapshot no longer matched a fresh resolution. The snapshot has been regenerated from currentmainand the sync gate now accepts it.Validation
origin/main...HEAD: passedpip-auditagainst the hashed snapshot: no known vulnerabilities foundgit diff --check: passedBandit and secret scanning remain intentionally outside this focused PR.
Disclosure: Updated on behalf of @PascalThuet by Codex (model: GPT-5, autonomous).