The two properties
intact — sequence
Each row carries a digest over its own content and the previous row’s digest.
intact: true means the sequence was not altered after it was written.It says nothing about who wrote it.signature_valid_rows — authorship
Each signed row carries a signature made inside the process, with that
process’s SVID private key.
signature_valid_rows counts rows whose signature verifies and whose
certificate chains to the SPIFFE trust root.A chain can be perfectly intact and entirely unsigned. That is still useful — it proves nobody edited history — but it is not proof that a particular agent did a particular thing.intactproves the SEQUENCE was not altered after it was written; it does not prove authorship.signature_valid_rowsproves AUTHORSHIP: those rows were signed inside a SPIRE-attested process and the signature chains to the SPIFFE trust root. The two are independent — a chain can be intact and unsigned, or signed and broken.
Reading the fields
boolean
The hash chain holds. If
false, break_at_index and break_at_row_id name
the exact row where it stops.integer
Rows carrying a signature at all.
integer
Rows whose signature verifies against the configured trust bundle. This is
the number that matters for authorship.
integer
Signed, but the signature does not verify. Any non-zero value here is serious
and should be investigated before anything else.
integer
Signed, but the certificate does not chain to the configured trust bundle —
typically a row written under a trust domain the verifier does not have. Not
the same as invalid: the signature may be perfectly good and simply
unattributable here.
integer
Rows outside the hash chain, usually predating chaining being enabled. They
are not evidence of tampering; they are evidence of age.
boolean
Whether the store has a trust bundle at all. If this is
false, every
signature result is meaningless — the store cannot verify anything.The store rejects what it cannot verify
A row whose signature does not chain to the configured trust bundle is refused at write time:The most common cause is a trust bundle that has not caught up with a trust
domain change. The evidence store caches its bundle at start, so after
re-pointing a data plane at a different root, restart the evidence API before
expecting signed rows to land.
What a signed row does not prove
Worth stating before an auditor asks.- It proves which process made the call — not that the call was correct, authorised by a human, or a good idea.
- It proves the row was written inside an attested process — not that the process was uncompromised. A compromised agent signs its own actions perfectly well. What you gain is that those actions are attributable and bounded, not that they were prevented.
- Absence of a row is not proof that nothing happened. A process with no identity writes no evidence — which is precisely why discovering uninstrumented processes is a separate control. See Per-process identity.
Related
- Per-process identity
- Multi-tenancy — why a row may be unverifiable in one tenant and valid in another
- Compliance frameworks