Skip to content

ci: add dependency audit workflow#3138

Open
PascalThuet wants to merge 2 commits into
github:mainfrom
PascalThuet:split/dependency-audit
Open

ci: add dependency audit workflow#3138
PascalThuet wants to merge 2 commits into
github:mainfrom
PascalThuet:split/dependency-audit

Conversation

@PascalThuet

@PascalThuet PascalThuet commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Part of splitting #2442 into smaller, dedicated PRs. This is the original #2438 ask — the dependency-audit workflow — re-derived against current main.

What

  • New .github/workflows/security.yml with dependency-audit coverage split by trigger:
    • push / PR / manual: one deterministic dependency-audit job audits the committed .github/security-audit-requirements.txt snapshot with pip-audit --require-hashes.
    • weekly schedule: dependency-audit-scheduled compiles the runtime + test dependency set live per (os, python) matrix entry (ubuntu/windows × 3.11/3.12/3.13) and audits that, to catch newly published advisories the committed snapshot wouldn't.
  • .github/scripts/check_security_requirements.py: a sync gate that fails a PR which changed pyproject.toml (or the snapshot) without regenerating the committed requirements.
  • .github/security-audit-requirements.txt: the committed --universal --generate-hashes snapshot (generated against current main).
  • tests/test_security_workflow.py: static guards for the jobs, matrix, pins, hashed snapshot, and the sync script. Triggers are asserted by inclusion so the follow-up baseline-gate PR can add labeled/unlabeled without rewriting the test.
  • CONTRIBUTING.md: a "Security checks" subsection documenting the local commands.

Why

Gives CI a deterministic dependency-advisory signal on every PR plus a live scheduled sweep, without a lockfile or redundant PR matrix runs.

Validation

  • tests/test_security_workflow.py — 12 passed.
  • uvx ruff check .github/scripts/check_security_requirements.py tests/test_security_workflow.py is clean.
  • pip-audit --require-hashes against the committed snapshot reports no known vulnerabilities.
  • A fresh uv pip compile ... --no-header is byte-identical to the committed snapshot (sync gate passes).
  • Actions pinned to commit SHAs (actions/checkout aligned to the repo-standard 9c091bb... # v7.0.0).

Bandit + secret-scan gates are deliberately not here — they come in a follow-up PR so each gate reviews on its own. Independent of the other split PRs.

Disclosure: Updated on behalf of @PascalThuet by Codex (model: GPT-5, autonomous).

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.
@PascalThuet PascalThuet requested a review from mnriem as a code owner June 23, 2026 21:51
Assisted-by: Codex (model: GPT-5, autonomous)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.yml with split triggers: deterministic audit for PR/push/manual + scheduled live-resolution audit matrix.
  • Added .github/scripts/check_security_requirements.py and 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

Comment on lines +21 to +25
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 2

Comment on lines +66 to +71
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 mnriem left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please address Copilot feedback

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.

3 participants