On this page
ADR-0034: The base image ships its OpenVEX statements, and derived images apply them
Status: Accepted (WP-20). Implemented in projects/base/image/vex/base.openvex.json and the template's scripts/scan.sh.
Context
Scanners match vulnerabilities by package name and version. The rebuilt BusyBox keeps
Alpine's package entry (ADR-0020),
so Grype reports CVE-2025-60876 (BusyBox wget) although the wget applet does not exist
in the binary. Every derived image would inherit the same false positive.
Decision
- The base image carries its OpenVEX document at
/usr/share/commonlayer/vex/, with the statementnot_affected/vulnerable_code_not_presentfor that CVE onbusyboxandbusybox-binsh. - The shared
scan.shapplies the base VEX (plus the project's ownsecurity/vex.openvex.json) when it evaluates the scan gate for every derived image.
Consequences
- The scan results recorded in the status files show the two suppressed matches explicitly (for example "Suppressed by VEX: 2"); without the VEX each image has two Medium findings.
- A VEX statement is a claim. It is only as good as the reason behind it; here the build enforces that the applet is absent, and the image tests check it.