feat: support multiple package digests with acquisition sources
Description
Trivy keeps exactly one digest per package in Package.Digest.
That value says nothing about where it came from or which bytes it covers, and the values we collect today differ in both respects:
| Ecosystem | Digest | Source and covered bytes |
|---|---|---|
| RPM | MD5 | SIGMD5 tag from the RPM DB: the main header and the payload, not the whole .rpm file |
| Debian | SHA-256 | SHA256 field in /var/lib/dpkg/available: the complete distributed .deb |
| Alpine | usually SHA-1 | C: field of the installed database: the compressed control stream, not the whole .apk |
| Java | SHA-1 | computed by Trivy over each archive, including nested JARs |
| Python | SHA-1 | computed by Trivy over the METADATA or PKG-INFO file, not over the distributed package |
RPM databases already hold several digests: SIGMD5 covers the main header and the payload, SHA256HEADER covers the header, PAYLOADDIGEST covers the compressed payload, and on some images PACKAGEDIGESTS carries SHA-256 and SHA-512 of the complete archive.
Trivy collects SIGMD5 only.
Replacing one value with another is not an option.
On images without PACKAGEDIGESTS, switching to a full-archive SHA-256 would remove the digest coverage that exists today.
Replacing Java's long-standing SHA-1 output with SHA-256 would break consumers that we can neither enumerate nor survey in OSS: removing such output requires advance notice and a migration period.
Proposal
Let a package keep several digests, each with its own algorithm, value and acquisition source, so that existing and additional values can coexist.
- Values with the same algorithm but different sources must remain distinguishable.
- The source identifies the originating metadata field or the computation method, and is documented so that consumers can determine the covered bytes from it.
- Values and their sources are preserved through cache serialization, RPC, the Trivy JSON output, and the conversion between the package model and the shared SBOM model.
- The existing
Digestfield in JSON and the current CycloneDX and SPDX output stay unchanged. - Values imported from outside Trivy's analyzers, such as an SBOM or an older client, get an explicitly unknown source; their provenance is never guessed.
Out of scope
Collecting additional values (more RPM tags, Python lock files, Go), changing where digests are placed in SBOM formats, and deprecating or removing the current SIGMD5 output are separate stories that need their own compatibility and migration decision.
Source: aquasecurity/trivy