build: hash-pin dependencies + SBOM + blocking pip-audit (closes #3)#9
Conversation
…p-audit Closes the P0.3 supply-chain item from NEXT_STEPS.md. - requirements.lock: fully hash-pinned tree (pip-compile --generate-hashes). requirements.txt stays the human-edited input; CI installs the lock with `pip install --require-hashes` for reproducible builds. - CI: test job installs from the lock; pip-audit is now BLOCKING against the locked tree (currently 0 known CVEs); new SBOM job emits a CycloneDX artifact (argus-sbom.cdx.json) via cyclonedx-bom (SHA-pinned upload-artifact). - Verified locally: hashed install + 81 tests pass in a clean venv; pip-audit --strict clean; SBOM = CycloneDX 1.6, 43 components. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PH7w1wBoUxFESq9gh6yjAQ
Reviewer's GuideIntroduces a hash-pinned dependency lockfile and updates CI to install from it, makes pip-audit a blocking gate against the locked tree, adds a CycloneDX SBOM generation workflow, and documents the new process in NEXT_STEPS and requirements.txt. Flow diagram for the new dependency locking and CI audit/SBOM processflowchart TD
dev[Developer edits requirements.txt]
lock[Run pip-compile --generate-hashes to create requirements.lock]
ci_test[CI test job installs with pip install --require-hashes -r requirements.lock]
ci_deps[CI deps job runs pip-audit -r requirements.lock --strict]
gate{pip-audit passes?}
ci_sbom[CI sbom job runs cyclonedx-py requirements requirements.lock]
artifact[Upload argus-sbom.cdx.json as artifact]
dev --> lock --> requirements_lock[requirements.lock]
requirements_lock --> ci_test
requirements_lock --> ci_deps
ci_deps --> gate
gate -->|yes| ci_sbom
gate -->|no| fail["Fail pipeline (blocking deps job)"]
ci_sbom --> artifact
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 2 issues, and left some high level feedback:
- In the SBOM job,
cyclonedx-pywritesargus-sbom.cdx.jsonto the default working directory, but the upload step points toaegis/argus-sbom.cdx.json; align the output location or the artifact path so the file is actually found.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In the SBOM job, `cyclonedx-py` writes `argus-sbom.cdx.json` to the default working directory, but the upload step points to `aegis/argus-sbom.cdx.json`; align the output location or the artifact path so the file is actually found.
## Individual Comments
### Comment 1
<location path=".github/workflows/ci.yml" line_range="28-32" />
<code_context>
cache: pip
- cache-dependency-path: aegis/requirements.txt
- - name: Install deps
+ cache-dependency-path: aegis/requirements.lock
+ - name: Install deps (hash-pinned)
run: |
python -m pip install --upgrade pip
- pip install -r requirements.txt
+ pip install --require-hashes -r requirements.lock
- name: Run test suite
run: python -m pytest -q
</code_context>
<issue_to_address>
**issue (bug_risk):** Lockfile path usage is inconsistent between cache configuration and install command.
`cache-dependency-path` references `aegis/requirements.lock`, while the install and SBOM steps use `requirements.lock` without the `aegis/` prefix. If the file is under `aegis/`, those commands will fail; if it’s at the repo root, the cache path is incorrect. Please pick a single location for the lockfile and update all references to match.
</issue_to_address>
### Comment 2
<location path=".github/workflows/ci.yml" line_range="77-81" />
<code_context>
+ run: |
+ pip install cyclonedx-bom==7.3.0
+ cyclonedx-py requirements requirements.lock -o argus-sbom.cdx.json
+ - name: Upload SBOM artifact
+ uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
+ with:
+ name: argus-sbom
+ path: aegis/argus-sbom.cdx.json
secrets:
</code_context>
<issue_to_address>
**issue (bug_risk):** SBOM output path and uploaded artifact path appear to be mismatched.
The SBOM is written as `argus-sbom.cdx.json` in the current directory, but the upload step looks for `aegis/argus-sbom.cdx.json`. Unless the job changes directories, the upload will fail due to a missing file. Please align the output and upload paths (either write to `aegis/argus-sbom.cdx.json` or adjust the upload path).
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| cache-dependency-path: aegis/requirements.lock | ||
| - name: Install deps (hash-pinned) | ||
| run: | | ||
| python -m pip install --upgrade pip | ||
| pip install -r requirements.txt | ||
| pip install --require-hashes -r requirements.lock |
There was a problem hiding this comment.
issue (bug_risk): Lockfile path usage is inconsistent between cache configuration and install command.
cache-dependency-path references aegis/requirements.lock, while the install and SBOM steps use requirements.lock without the aegis/ prefix. If the file is under aegis/, those commands will fail; if it’s at the repo root, the cache path is incorrect. Please pick a single location for the lockfile and update all references to match.
| - name: Upload SBOM artifact | ||
| uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 | ||
| with: | ||
| name: argus-sbom | ||
| path: aegis/argus-sbom.cdx.json |
There was a problem hiding this comment.
issue (bug_risk): SBOM output path and uploaded artifact path appear to be mismatched.
The SBOM is written as argus-sbom.cdx.json in the current directory, but the upload step looks for aegis/argus-sbom.cdx.json. Unless the job changes directories, the upload will fail due to a missing file. Please align the output and upload paths (either write to aegis/argus-sbom.cdx.json or adjust the upload path).
Summary
Implements P0.3 from
aegis/docs/NEXT_STEPS.md— the supply-chain hardening that lets the dependency-audit gate become meaningful. Closes #3.Changes
aegis/requirements.lock— fully hash-pinned dependency tree generated withpip-compile --generate-hashes.requirements.txtstays the human-edited input (with a regeneration note); CI installs the lock withpip install --require-hashesfor reproducible builds..github/workflows/ci.yml):testjob installs fromrequirements.lock(hash-verified).pip-auditis now blocking (was informational) against the locked tree.sbomjob emits a CycloneDX SBOM (argus-sbom.cdx.json) as a build artifact viacyclonedx-bom; upload uses the SHA-pinnedupload-artifact.Testing (local)
pip install --require-hashes -r requirements.lock→ 81 tests pass.pip-audit -r requirements.lock --strict→ 0 known vulnerabilities.Follow-up
The lock currently includes the dev/test dep (
pytest) sincerequirements.txtmixes runtime and dev. Splitting runtime vs dev deps (so the SBOM reflects runtime only) is a minor future refinement.🤖 Generated with Claude Code
Generated by Claude Code
Summary by Sourcery
Introduce a hash-pinned dependency lockfile, enforce reproducible and vulnerability-audited installs in CI, and generate a CycloneDX SBOM as a build artifact.
New Features:
Enhancements:
Build:
CI: