Comparing to upstream
How the "Why hardened" comparison panel computes its numbers — and why we don't lie about the times we don't win.
Every image's detail page has a "Why hardened" panel showing PodArmor side-by-side with the upstream image we replace. The reduction stats — "X% fewer outstanding patches · Y% smaller" — are computed on data we record from real scans, not marketing.
How the upstream baseline is built
For every PodArmor image we publish, we keep a recorded baseline of the upstream image it replaces. The baseline is captured by running grype <upstream-image> -o json against the public upstream tag and recording the result. Each entry contains:
{
upstreamImage: "eclipse-temurin:17-jre",
scannedAt: "2026-05-12T00:00:00Z",
upstreamCves: { critical, high, medium, low, total },
upstreamFixable: 11, // count of CVEs with fix.state === 'fixed'
upstreamSizeBytes: 294_472_590,
notes: "..."
}The numbers come from grype <image> -o json with no flags — no --only-fixed, no severity gates. Same input shape we'd accept from a customer's own scan.
How we compute the reduction
| Metric | Formula |
|---|---|
% fewer outstanding patches | (upstream.fixable - ours.outstanding) / upstream.fixable × 100 |
% fewer CVEs (raw) | (upstream.total - ours.total) / upstream.total × 100 |
% smaller (size) | (upstream.size - ours.size) / upstream.size × 100 |
Fixable cut | upstream.fixable - ours.outstanding |
The headline number on the comparison card is always the outstanding-patches reduction, not the raw-CVE-count reduction. The raw count can be misleading because distros classify residuals differently — see CVE classification.
When we lose on the raw count
For some deploy images (e.g. a hardened JRE built on Debian distroless vs the official eclipse-temurin:17-jre which ships on Ubuntu), the raw CVE count on our side is actually higher than upstream's. This happens because the two distros classify the same underlying glibc surface differently — Debian flags many entries as wont-fix (still visible in the scanner output), Ubuntu publishes them as fixable-via-apt.
The honest framing — what the page actually shows — is:
"Our 19 CVEs are all unfixable residuals (no patch exists or the maintainer ruled it doesn't need one). Upstream's 11 CVEs are all
fixable— patches you'd need to chase yourself."
The reduction stats reflect this:
- Outstanding cut: −11 (we ship zero outstanding; upstream's 11 are all outstanding)
- Size cut: −128 MB (45% smaller) (real and dramatic)
- Raw CVE count: deliberately NOT surfaced as a reduction stat in this case (we hide negatives rather than show "−8")
A reviewer who scrolls past the explanation still sees the "0 vs 11" outstanding-patches comparison, which is the metric that actually maps to "what would the customer have to do."
When we win on every axis
For build images (a PodArmor hardened build image vs the public maven:3.8.3-openjdk-17), we typically win on raw count, outstanding count, AND size simultaneously. A representative comparison: ~88% fewer outstanding patches, ~48% smaller image, and a Fixable cut: −442 reduction strip the side-by-side panels make obvious. Numbers vary per image and refresh on every rebuild.
When we don't win at all
We never have. But if it ever happens (e.g. we ship a regression), the headline collapses to:
"Built with PodArmor's hardening baseline"
— with no reduction stat. The customer can still verify what we DO ship via the HardeningBadges and the linked CIS Section 4 alignment.