Skip to main content

Vulnerability analysis

Every image Zero publishes is analysed for known vulnerabilities. The analysis runs per digest — the exact identifier of the bytes that are running — and is repeated daily, because what is known about an image changes even when the image does not.

Three different answers, which the platform never blends​

"Does this deployment have vulnerabilities?" has three answers, and two of them look alike when written carelessly:

AnswerWhat it meansHow it appears
Nothing foundThe analysis completed and found no known vulnerability"No vulnerabilities found in this analysis"
FoundThe analysis completed and found someCounts by severity, with how many have a fix
Could not analyseThe analyser did not complete — image registry down, timeout, unreadable report"The analysis did not complete", with no counts at all

The third is the one that matters. A zero count from an analysis that did not complete is not an image without vulnerabilities: it is the absence of information. So when the analysis fails, the platform does not show zeros — it says it does not know.

No findings is a statement about the analysis, not about the image

"No vulnerabilities found in this analysis" is a statement about that analysis, on that day, with that vulnerability database. The platform never writes "image is secure": no analyser can assert that, and promising it is the beginning of the cycle where nobody looks any more.

When the analysis happens​

On deploy. After the image is built and its integrity is confirmed, and before the deployment is declared active. That is the only moment when the final digest already exists, is immutable, and the deployment has not gone live yet.

Every day. The image does not change; what is known about it does. A vulnerability published today describes a package that was already there last week, and last week's analysis could not have found it. The daily review covers what is live and the recent versions a rollback could return to.

That is why the same image shows different results on different days, and why the screen shows which analyser and which database produced each result. It answers "why did nothing show up yesterday?".

Finding a vulnerability does not block publishing​

Zero's current policy is observe: the analysis is mandatory, the result is visible, and nothing is blocked because of it.

The reason is practical. A platform that blocks deployment on an analyser finding teaches people to turn the analyser off — and the first critical finding with no published fix would block a service that was already live and working, over information nobody can act on at that moment.

What the platform does is show, and warn:

  • on the project's Security screen, per service, with the counts and the list;
  • in Alerts, when there is a critical vulnerability in the image that is running;
  • in Alerts, at warning severity, when the analysis did not complete — because what is wrong there is not the image, it is the information about it.

Fix available, unavailable, unknown​

Every finding carries the state of its fix, and there are three:

StateWhat to do
Fixed in x.y.zUpdating the package resolves it
No published fixThe maintainer declared it will not be fixed, or the version reached end of life
Fix unknownThe analyser asserted nothing — a fix may exist

The third state exists on purpose. Translating "I don't know" into "there is no fix" makes operators stop looking for a fix that may well exist.

Where that state comes from​

From the field the analyser uses to declare what it knows, not from the presence of a version number. fixed becomes "fixed"; will_not_fix, end_of_life, fix_deferred and affected become "no published fix"; everything else becomes "unknown".

When the same problem is fixed on several branches​

Common in language packages. The analyser delivers it like this:

installed: 6.2.1
fixed: 10.2.3, 9.0.7, 8.0.6, 7.4.8, 6.2.2, 5.1.8, 4.2.5, 3.1.4

Eight branches, and the one that serves someone on 6.2.1 is 6.2.2 — not the first in the list. Zero shows all of them and does not pick for you: picking would mean comparing versions inside each ecosystem's own rules (apk, dpkg, rpm, semver), and a wrong pick would tell you to jump two majors over a patch.

When the analyser lists several branches without declaring the fix state, Zero answers unknown rather than available: fixes exist, and which one is yours has not been stated.

From the command line​

zero security <service> # summary of the analysis of what is live
zero security <service> --findings # the list of vulnerabilities

The exit code follows the answer, and that is what a script should read:

CodeMeaning
0The analysis completed — with or without findings
3The analysis did not complete: there is nothing to assert about the image
1The command failed (network, credentials, no such service)

A script that treats 3 as 0 turns an image registry outage into a clean image report. The separate code exists precisely to prevent that.

From the API​

GET /services/{serviceId}/security/scan the summary
GET /services/{serviceId}/security/findings the list, cursor-paginated

In the summary, three fields answer different questions and do not substitute for one another:

  • status — what happened to the analysis. Only succeeded completed.
  • the counts — what it found. They only mean anything when status is succeeded.
  • decision — what the policy concluded. scan_failed is deliberately different from allow.

scanned: false means nobody analysed that digest — never that it is clean.

The findings list comes ordered by severity and paginated by cursor. An empty list is also the answer when no analysis completed: whoever needs to tell them apart reads status in the summary.