rfgen.supply_chain_evidence¶
rfgen.supply_chain_evidence qualifies a release from caller-supplied,
already-parsed evidence. It is a deterministic, offline policy boundary: it
does not read artifact files, invoke Syft, Trivy, or Cosign, contact a
registry, or create a scan, signature, provenance statement, or report.
The caller owns evidence collection and parsing. This module owns strict model
validation, hash and identity comparisons, vulnerability-exception policy, and
the resulting PASS or FAIL decision.
All record models are source-backed, strict, frozen Pydantic models:
extra="forbid" rejects unknown fields, strict validation does not coerce
input values, and accepted instances cannot be mutated. They describe facts
obtained from retained release evidence; they are not a way to manufacture
those facts. SHA-256 values are exactly 64 lowercase hexadecimal characters;
source_revision is exactly 40 lowercase hexadecimal characters.
Closed vocabularies¶
SupplyChainStatus¶
PASS or FAIL, the status stored in a report and returned by verification.
ArtifactKind¶
The complete release artifact set: OCI_AMD64, OCI_ARM64, SDIST, and
WHEEL. A passing report contains each kind exactly once.
VulnerabilitySeverity¶
LOW, MEDIUM, HIGH, or CRITICAL. Only HIGH and CRITICAL findings
participate in the exception decision.
Artifact and parsed-evidence models¶
SupplyChainArtifactV1¶
class SupplyChainArtifactV1(BaseModel):
id: str
kind: ArtifactKind
sha256: Sha256
sbom_sha256: Sha256
scan_sha256: Sha256
signature_bundle_sha256: Sha256
provenance_sha256: Sha256
The release report’s hash commitments for one distributable artifact. The verifier compares every field with the corresponding parsed evidence; it does not calculate these hashes from files.
VulnerabilityFindingV1¶
class VulnerabilityFindingV1(BaseModel):
cve: str
severity: VulnerabilitySeverity
One caller-parsed scan finding. cve must match CVE-<year>-<number> and the
model never invokes a scanner.
ParsedArtifactEvidenceV1¶
class ParsedArtifactEvidenceV1(BaseModel):
artifact_sha256: Sha256
sbom_sha256: Sha256 | None
scan_sha256: Sha256 | None
signature_bundle_sha256: Sha256 | None
provenance_sha256: Sha256 | None
signature_verified: bool
provenance_verified: bool
identity: str | None
issuer: str | None
syft_version: str
trivy_version: str
cosign_version: str
cyclonedx_schema_version: Literal["1.6"]
slsa_schema_version: Literal["1.0"]
findings: tuple[VulnerabilityFindingV1, ...] = ()
The adapter supplies facts parsed from real, externally produced evidence.
The version policy is exact at the compatibility boundary: Syft must be a 1.x
release; Trivy must be 0.58.0 or newer; Cosign must be a 2.x release;
CycloneDX must be schema 1.6; and SLSA provenance must be schema 1.0. Version
strings outside those policies are rejected rather than treated as
approximately compatible. signature_verified and provenance_verified are
inputs from that caller-owned verification process; setting either flag does
not perform verification here.
Absent evidence hashes, failed flags, mismatched policy identity or issuer, or unexcepted high-severity findings make verification fail. A caller must not fabricate evidence, a successful scan result, a signature result, or a provenance result to satisfy this record contract.
SupplyChainEvidenceAdapter¶
class SupplyChainEvidenceAdapter(Protocol):
def evidence_for(
self, artifact: SupplyChainArtifactV1
) -> ParsedArtifactEvidenceV1 | None: ...
The narrow injection seam for parsed evidence. It returns evidence for the
requested artifact, or None when it is unavailable. It is not a scanner or
verification plugin interface: its implementation must preserve the boundary
above and return only caller-parsed facts.
Policy, exception, and report models¶
SupplyChainPolicyV1¶
class SupplyChainPolicyV1(BaseModel):
identity: str
issuer: str
The non-empty signing identity and issuer required for every signed artifact and the report itself.
VulnerabilityExceptionV1¶
class VulnerabilityExceptionV1(BaseModel):
cve: str
severity: VulnerabilitySeverity
owner: str
expires_at: date
mitigation: str
evidence_sha256: Sha256
One owned, time-limited exception. It must expire no earlier than today and no
later than 30 days from today at construction. During verification an exception
binds to exactly one finding: its CVE and severity must exactly match that
finding, it must not be expired at as_of, and its evidence_sha256 must
equal the parsed scan hash that produced the finding. An exception cannot
waive a different CVE, a different severity, a different scan, or a missing
scan hash.
SupplyChainReportV1¶
class SupplyChainReportV1(BaseModel):
schema_version: Literal[1]
source_revision: GitSha
artifacts: tuple[SupplyChainArtifactV1, ...]
exceptions: tuple[VulnerabilityExceptionV1, ...]
identity: str
issuer: str
status: SupplyChainStatus
causes: tuple[str, ...]
report_sha256: Sha256
The canonical release-qualification record. Artifacts are unique and sorted by
(kind, id); exceptions are unique and sorted by CVE. report_sha256 must be
the SHA-256 of the RFC 8785 canonical JSON representation after removing only
report_sha256 itself.
A PASS report has all four artifact kinds exactly once and no causes. A
FAIL report has at least one non-empty cause. Constructing a valid report
only validates its internal record shape and self-hash; it does not prove the
referenced evidence exists or is authentic.
SupplyChainVerificationResultV1¶
class SupplyChainVerificationResultV1(BaseModel):
status: SupplyChainStatus
causes: tuple[str, ...]
The immutable result of a verification attempt. Every discovered problem is
retained in causes so release tooling can report all evidence gaps together.
Offline verifier¶
ParsedEvidenceSupplyChainVerifier¶
class ParsedEvidenceSupplyChainVerifier:
def __init__(
self, *, adapter: SupplyChainEvidenceAdapter, policy: SupplyChainPolicyV1
) -> None: ...
def verify(
self, report: SupplyChainReportV1, *, as_of: date | None = None
) -> SupplyChainVerificationResultV1: ...
Checks only the self-authenticated report and parsed evidence supplied by the
adapter. For every report artifact it requires evidence, all five matching
hashes, verified signature and provenance flags, and matching identity and
issuer. It also rejects unexcepted HIGH or CRITICAL findings and invalid,
expired, or scan-hash-mismatched exceptions.
as_of makes exception expiry deterministic for offline runs. If omitted,
the verifier uses the local current date. The result is PASS only when the
submitted report says PASS and no verification causes were found; otherwise
it is FAIL. The verifier never changes a report and never runs or simulates
external security tools.
See Also¶
Build and CI: required release evidence and the external-tool boundary.
Attestation: the separate Sigstore DSSE trust-root boundary.