Supply-chain rules¶
Rule-pack rigor-foundry/1.9.0 adds a bounded supply-chain category (prefix
SC) of high-precision rules over tracked Python requirement files. Like every
RigorFoundry rule, each SC finding is an anchored needs-evidence candidate,
never a verdict: it marks a real dependency-integrity surface for review, not a
proven compromise. The rules are deliberately narrow to keep false positives
low; breadth is not an acceptance metric.
Rules¶
| Rule | Signal | Confidence |
|---|---|---|
SC001-unhashed-pinned-requirement |
a pinned (==) requirement in a hash-mode lock file that carries no --hash= digest |
high |
SC002-vcs-url-requirement |
a dependency installed from a VCS checkout (git+, hg+, svn+, bzr+) or a PEP 508 direct URL (name @ https://…) |
high |
SC001 activates only for a requirement file that already demonstrates hash
mode — at least one line carries a --hash= digest — and then flags any pinned
requirement in that file with no accompanying hash. Such a gap means the
artefact is installed without verification against tampering or index
substitution. It is near-zero false-positive by construction: pip-compile
--generate-hashes output hashes every entry, so a missing hash is a genuine
integrity hole and not a stylistic choice. SC002 flags a dependency resolved
outside the package index and its recorded hashes — a mutable, unverified
artefact.
Both rules parse requirement lines, joining backslash-continued blocks, and skip
comments and index-configuration options: --index-url https://…,
--extra-index-url, and --find-links are configuration, not dependencies, and
are not flagged. Scope is limited to files named requirements*.txt /
requirements*.in or any .txt / .in file under a requirements/ directory;
.in source inputs are never subject to SC001 because they carry no hashes by
design, but a VCS or URL dependency in an .in is still a real SC002 concern.
Each candidate carries a repository-tree anchor (path, line, content SHA-256), a
neutral rationale, and a concrete verification procedure — for SC001,
recompile the lock with --generate-hashes so every pin carries a digest; for
SC002, pin the dependency to an immutable released version from the index with
a recorded hash, or vendor and audit the exact revision if a direct source is
genuinely required.
Precision and applicability¶
The rules match on requirement structure, not on arbitrary text, so a URL inside
a comment or a non-requirements file is not flagged, and a fully hashed lock
produces no candidate. The category contributes a portable control toward the
supply-chain audit domain over the tracked requirement surface, so a
repository that declares that domain required is now covered by a portable rule
as well as any wired native adapter (for example a Trivy or Grype profile).
Calibration¶
False-positive calibration against real repositories is deliberately separate work: these rules ship with safe-and-vulnerable fixtures and precise requirement parsing, but adjudicated false-positive and reviewer-effort evidence across adopter repositories is the maturity-lifecycle step that promotes a rule from candidate breadth to calibrated enforcement.