Problem
PEP 440 local version identifiers (the +local suffix, e.g. 1.2.3+rhai.22) are discarded by claircore's Python package scanner. The pep440.Version struct has no Local field, and the godoc comment states explicitly: "Local revisions are discarded." v.String() reconstructs from Epoch, Release, Pre, Post, Dev only — the local segment is permanently gone from the package record after indexing.
This causes false positive CVE reports for downstream-patching workflows: when a packager (e.g. Red Hat +rhai* builds) backports a CVE fix into a local version increment, Clair reports the package as still vulnerable. It compares the stripped version (1.2.3) against the CVE database, which still lists 1.2.3 as affected. The local version that signals the fix is present is invisible to Clair and to readers of the clair scan report.
Proposed Change
Add an opt-in flag to the Python ScannerConfig:
type ScannerConfig struct {
ReportLocalVersion bool `json:"report_local_version" yaml:"report_local_version"`
}
When true, emit hdr.Get("Version") directly instead of v.String(). Default false — behavior is unchanged for all existing users. Public PyPI does not permit local versions, so no standard-index user would ever see a local version in Clair output; this only affects private registries and downstream patching workflows. (hdr in the above is the raw Version header from the package metadata)
This change affects scan output format only. Vulnerability matching uses NormalizedVersion (a separate field) and is not affected.
# Current output
"Version": "1.2.3"
# With ReportLocalVersion: true
"Version": "1.2.3+rhai.22"
Impact
- No behavior change for default users (opt-in, default off)
- Downstream consumers of Clair scan output (e.g. policy evaluation engines like Enterprise Contract) can distinguish patched builds (1.2.3+rhai.22) from unpatched ones (1.2.3)
Problem
PEP 440 local version identifiers (the +local suffix, e.g. 1.2.3+rhai.22) are discarded by claircore's Python package scanner. The pep440.Version struct has no Local field, and the godoc comment states explicitly: "Local revisions are discarded." v.String() reconstructs from Epoch, Release, Pre, Post, Dev only — the local segment is permanently gone from the package record after indexing.
This causes false positive CVE reports for downstream-patching workflows: when a packager (e.g. Red Hat +rhai* builds) backports a CVE fix into a local version increment, Clair reports the package as still vulnerable. It compares the stripped version (1.2.3) against the CVE database, which still lists 1.2.3 as affected. The local version that signals the fix is present is invisible to Clair and to readers of the clair scan report.
Proposed Change
Add an opt-in flag to the Python ScannerConfig:
When true, emit hdr.Get("Version") directly instead of v.String(). Default false — behavior is unchanged for all existing users. Public PyPI does not permit local versions, so no standard-index user would ever see a local version in Clair output; this only affects private registries and downstream patching workflows. (hdr in the above is the raw Version header from the package metadata)
This change affects scan output format only. Vulnerability matching uses NormalizedVersion (a separate field) and is not affected.
Impact