What zero-trust means for a scanner

Why ZTVS attaches evidence to every finding, and what that rules out.

"Zero trust" is usually said about networks: authenticate every request, trust no segment, assume the perimeter has already failed. Applied to vulnerability scanning it means something specific.

The claim a scanner usually makes#

A conventional scanner reads a manifest — a lockfile, an OS package database, an SBOM generated in CI last quarter — and reports what the manifest says. The output looks factual. It is a claim about a claim.

That holds right up until the manifest and the artefact disagree, which they do constantly: a dependency vendored by hand, a binary patched in place, a base image rebuilt under the same tag.

What ZTVS does instead#

Every finding carries the evidence that produced it — which source, which file, which line or layer digest — as its justification rather than as a debugging aid.

Since 0.0.2 there is a second step: resolved packages are verified against the artefact. The verified 412/412 line in the scan output is the scanner saying it checked, not assumed. Where lockfile and disk disagree, the disagreement is itself reported.

The three questions, and which version answers them#

Question Answered by
What is present? 0.0.1 — resolution with evidence
Is what is present what the manifest claimed? 0.0.2 — on-disk verification
Did this report really come from this scanner? 0.0.2 — attestation

The third is the one people skip. A report is evidence only if a person who distrusts you can check it, and until 0.0.2 nobody could.

What this still does not give you#

  • ZTVS verifies what is present, not that what is present is what you intended.
  • An attestation proves the report is unaltered. It does not prove the scan was correct — different claim, and conflating them is how a signature ends up trusted more than it deserves.
  • Advisory data remains someone else's claim. ZTVS records which database and snapshot it used, so the claim is attributable.

Why suppression is loud#

A suppressed finding stays in the report with its reason and expiry attached. It is tempting to make suppressions disappear — the dashboard looks better. But a suppression is a decision someone made, and decisions that vanish from the record get remade badly. review_by is required for the same reason: an accepted risk without a date is an accepted risk forever.