The wire format is specified in full here:
If you have not written one yet, start with Write a policy, then read the CLI reference. The 0.0.1 behaviour is described in the old tutorial, and the source lives on GitHub.
An attestation is a signed statement about a subject. ZTVS signs reports so that a report can travel — into a compliance system, a customer's review, an incident timeline — without the recipient having to trust whoever forwarded it.
The chain#
Each input is pinned by digest, so the attestation says: this scanner, with this advisory data, under this policy, over this artefact, produced exactly these bytes.
What it proves#
- The report has not been modified since signing
- The scanner version is as claimed
- The advisory snapshot is as claimed
- The policy applied is as claimed
What it does not prove#
- That the scanner is free of bugs
- That the advisory data is complete or correct
- That the target was the one you meant to scan
The third is worth sitting with. The attestation binds a report to a digest. Whether that digest is the artefact you shipped is a question about your build pipeline, not about ZTVS. Signing does not import trust from elsewhere; it only stops trust leaking on the way.
Where the trust sits#
Exactly one place: the key. Everything else in the chain is verifiable by computation.
That makes key handling the whole security story:
- The signing key should live where the scanner runs, not in a shared secret store that a dozen jobs can read
- Retired public keys stay published as long as the reports they signed are retained, or those reports become unverifiable
- A key that signs both scans and releases collapses two trust domains into one — keep them separate
If you can only do one thing, make the signing key ephemeral and bind it to the CI job identity. A key nobody holds cannot be stolen from anybody.