Probity Predicate Standard, v1
An open, vendor-neutral format for signed, offline-verifiable security verdicts about software artifacts and agent servers. A verdict says, in cryptographically checkable form, that a named artifact was run in isolation, attacked with a pinned corpus of exploits, and given a PASS / DEGRADED / FAIL outcome with per-class evidence. The format is the public surface; the runtime that produces it is out of scope for this standard.
The base URI for a predicate type in this standard is:
https://getprobity.dev/predicate/v1/<name>
One exception: adversarial-execution-evidence.md is proposed for
standardization in the in-toto attestation namespace and carries its own type URI
(https://in-toto.io/attestation/adversarial-execution-evidence/v0.7) rather than a
getprobity.dev one. A consumer always dispatches on the full predicateType string, so the
namespace split is transparent to verification.
Why this exists
A verdict is only useful to a third party if that party can read and trust it without trusting or re-running the tool that produced it. CI systems, admission controllers, auditors, and registries need a stable, documented schema they can parse offline and verify against a configurable trust anchor. This standard publishes that schema so any tool can emit a conforming verdict and any tool can verify one. The intent is interoperability: a single agreed-upon shape for "this artifact was adversarially tested and here is the signed result," before the surface fragments into mutually incompatible vendor schemas.
This document is the scope and governance index. Each component has its own self-contained specification (linked below). Read the envelope first; it is the substrate every predicate rides on.
Wave 1 components (this release)
Read in this order. The order is also the dependency order: later documents reference earlier ones.
| # | Document | predicateType | What it carries |
|---|---|---|---|
| 1 | signing-envelope.md | (envelope, predicate-agnostic) | DSSE PAEv1 + ed25519 envelope, key id, trust root, offline-verify procedure |
| 2 | vocabulary-registry.md | (registry, versioned) | The closed, versioned enums (layer, violation_type, sink, auth_downgrade_cause) and the governance process |
| 3 | catch-record.md | (component of the verdicts below) | The forensic catch-record: per-record host signature + batch Merkle root |
| 4 | security-verdict.md | .../security-verdict | Per-server scan verdict for a single artifact against an attack corpus |
| 5 | adversarial-execution-evidence.md | https://in-toto.io/attestation/adversarial-execution-evidence/v0.7 | Bounded adversarial-stimulus evidence for a scanned artifact (Tier-2 runtime, in the box): fused recomputable result, digest-committed coverage bound, per-attack containment chain, signed intercept records |
| 10 | static-scan-verdict.md | .../static-scan-verdict | Tier-1 detection verdict: static scan of the declared surface — no microVM, no runtime execution; verdict-bearing but carries no catch-policy binding |
| 9 | sut-provenance.md | .../sut-provenance | Build provenance of a scanned SUT image: a known base image plus a fully integrity-pinned dependency closure with a deterministic binding hash |
Substrate / mesh components (this release)
These predicates attest properties below the application and network perimeter - the isolation substrate itself and the composition of a mesh of microVMs running over it. Their distinguishing property is that a perimeter-only sandbox cannot emit them: the evidence is captured at the hypervisor memory boundary and from the host's view of the guest, not at a syscall or network shim. Each carries its own self-contained specification under the same envelope, vocabulary, and versioning model.
| # | Document | predicateType | What it carries |
|---|---|---|---|
| 6 | ml-bom.md | .../ml-bom | Execution-grounded model bill-of-materials: INTENT from a guest VMA walk, IDENTITY from a host-side 3-source resolver |
| 7 | mesh-quiescence.md | https://getprobity.dev/predicate/v2/mesh-quiescence | Freeze-atomicity attestation: bounded hypervisor-pause distributions, captured in-flight escape, closed-world egress |
| 8 | a2a-mesh-scorecard.md | https://getprobity.dev/predicate/v2/a2a-mesh-scorecard | Mesh composition-safety verdict over an aggregate MeshManifest subject (N member substrate roots + ModelBOM digests + hop graph) |
These three are format-and-verification stable and ship signed conformance bundles that verify offline
(see conformance.json). The shipped a2a-mesh-scorecard bundle binds a real sealed N=3 jailed mesh run
(honest_scope.substrate_roots_real == true, hop_graph_live == false): real per-member byte-identity
substrate roots with the canonical A->B->C delegation replayed, not observed live on the wire. Its
composition-safety verdict is the offline evaluate_mesh evaluator's verbatim escalation finding
(scope == "ESCALATED", causes == ["SCOPE_BROADENING"]). Where a capability behind a predicate is
still forward-looking - the egress-proxy ML-BOM identity source or a hardware host-trust root - the
relevant document's status/maturity section says so plainly.
Wave 2 (published, standardization track open)
The first two carry the substrate evidence a wave-1 verdict references but does not contain; the
third carries the bound around a published piece of evidence rather than any evidence itself. Their
formats, producers, and offline verification are stable and their specifications are
published here, so their type URIs resolve. What remains open is the standardization track: they
have not been through the cross-vendor review the wave-1 components had, and a wave-1 verifier is not
required to understand them. A consumer dispatches on the full predicateType string, so a verifier
that does not implement them rejects them cleanly.
| # | Document | predicateType | What it carries |
|---|---|---|---|
| 11 | signed-evidence.md | .../signed-evidence | One signature over the guest-memory Merkle commitment, the value-binding to a signed session and verdict subject, and the cross-host fold pins |
| 12 | substrate-integrity.md | .../substrate-integrity | The byteident proof families about the isolation substrate: fold-correctness, clone-uniqueness, and the VMGenID-reseed differential (entropy-uniqueness is retired and is a rejection target) |
| 13 | evidence-scope-disclosure.md | .../evidence-scope-disclosure | The bound around a published piece of evidence: the layers it covers, its tier, whether it is a capture or a representative fixture, and the producer's prose statement of what it does not show |
A wave-1 reference to a "substrate root" is an opaque digest plus a substrate_proof_type
discriminator naming the proof family; the proof itself is served alongside and verified out of band
against substrate-integrity.md.
Envelope summary
Every predicate in this standard is the predicate field of an
in-toto Statement v1
(_type: https://in-toto.io/Statement/v1), wrapped in a
DSSE envelope and signed with ed25519. The Statement
binds the predicate to a subject (one or more named digests - always the artifact the verdict is
about). The signature is computed over the DSSE Pre-Authentication Encoding (PAEv1) of the Statement,
never over bare bytes, so a signature for one payload type can never be replayed as another. Each
envelope MUST carry a keyid equal to the lowercase-hex SHA-256 of the RFC 7638 JWK thumbprint input
for the ed25519 public key. The full construction, the trust-root model, and a worked offline-verify
example are in
signing-envelope.md.
Versioning and forward-compatibility
The version is part of the contract and is encoded in the predicate type URI:
-
Major version in the URI. Every predicate type carries its major version in the path (
/predicate/v1/...). A consumer dispatches on the fullpredicateTypestring and MUST reject a predicate whose type it does not recognize. A new major version is a new URI. -
Additive-optional fields are a minor change and stay within the major version. A producer MAY add new optional fields. Adding an optional field does NOT change the major version.
-
A verifier MUST ignore unknown fields. This is the load-bearing forward-compatibility rule: a v1 verifier presented with a predicate that carries optional fields it does not know MUST NOT reject the predicate on that basis alone. It validates the fields it understands and ignores the rest. This lets producers ship additive fields without breaking deployed verifiers.
-
Rename, removal, or any semantic change of an existing field is a major version (v2). Changing what a field means, deleting it, or renaming it is breaking and requires a new major version URI. It is never shipped as a silent in-place change a deployed verifier is expected to tolerate.
Producer-strict vs verifier-tolerant (stated explicitly)
This standard deliberately holds two rules that look contradictory and are not. They apply to different parties:
-
A PRODUCER MUST be strict. A conforming producer emits only the fields defined for the predicate version it claims, and rejects its own output if it carries fields it does not recognize. Producer-side validation is closed: unknown field means a bug, refuse to sign.
-
A VERIFIER MUST be tolerant of additive fields. A conforming verifier ignores fields it does not recognize rather than rejecting the whole predicate, exactly so that a producer shipping a newer minor version can be read by an older verifier.
Strict-out, tolerant-in. The asymmetry is the mechanism that makes additive evolution safe. Note the one exception: vocabulary values are fail-closed at a version (see below) - a verifier MUST reject an unknown enum value even though it ignores an unknown field. The difference is that an unknown field is forward-compatible additive data, whereas an unknown enum value for a known field is a value the verifier cannot interpret and so cannot trust.
Vocabulary registry and governance
Some fields draw from closed enumerations (the layer, violation_type, and sink vocabularies
used by catch-record.md). These are not free text. They are published in a
versioned registry (vocabulary-registry.md) whose version is tied to
the predicate version.
-
The registry is fail-closed at a version: a verifier MUST reject any value not present in the registry version it knows. There is no warn-and-continue mode.
-
Adding a value is a registry revision, published as a new registry list, not a silent change a deployed verifier is expected to tolerate. Producers and verifiers move to a new registry version together.
-
Governance. Probity maintains the registry initially. Additions and changes go through a published contribution process (a
CONTRIBUTINGdocument and pull-request review). The intent is to graduate maintenance to a neutral, multi-party process as adoption grows; until then, changes are proposed in the open and reviewed before a new registry version is cut.
Related standards
This standard is built to compose with the existing supply-chain and security-finding ecosystem rather than replace it. Where it aligns and where it diverges:
-
in-toto attestation - ALIGNED. The envelope is an in-toto Statement v1; the subject-binding and
predicateTyperouting are used exactly as in-toto defines them. -
DSSE - ALIGNED. The signing envelope is DSSE with PAEv1. No deviation.
-
SLSA Verification Summary Attestation (VSA) - PARTIALLY ALIGNED. A Probity verdict plays a role similar to a VSA (a signed statement that a verification was performed and what it concluded). The engine-identity field in security-verdict.md is modeled on the VSA
builder.ididea (an auditor-pinnable identity for the thing that produced the verdict). Probity diverges in carrying adversarial per-attack results and a forensic evidence reference rather than a policy-evaluation summary. -
SARIF - CROSSWALK. Per-finding
check_idvalues in layer-carrying verdicts (see static-scan-verdict.md) map onto SARIF rule identifiers; a producer MAY carry findings as, or reference, a SARIF document. Probity does not re-specify SARIF; it points at it. (Layer findings are out of the adversarial-execution-evidence core; a producer that carries them does so via the_extextension convention - see adversarial-execution-evidence.md.) -
OpenVEX - ALIGNED for revocation. A verdict's trust in its attested substrate can be revoked out-of-band via an OpenVEX statement; the verifier consults a VEX log to void a stale PASS (see security-verdict.md).
-
CycloneDX - RELATED, not overlapping. CycloneDX describes what an artifact contains (a bill of materials). This standard describes what happened when the artifact was attacked. The two are complementary: a verdict's subject digest is the same artifact a CycloneDX BOM would describe.
Verifiable today vs roadmap (honesty section)
This standard is technically honest about what a third party can independently check versus what it must take as a producer self-assertion. Where a field is a self-assertion a verifier cannot verify on its own, the relevant document says so plainly. In summary:
Compliance-framework mapping. The crosswalk from one signed verdict to the controls of ten compliance frameworks — and which mappings are emitted-today vs roadmap (the OSCAL assessment-results document, the per-finding OWASP/ATLAS taxonomy tags, and the per-framework evidence packs are roadmap; we emit DSSE/in-toto + SARIF today) — is in compliance-crosswalk.md. Consumers MUST follow its bright line: a verdict's signature re-verifies offline; the framework mapping is an assertion of that crosswalk, never a claim that a bundle contains an OSCAL package or a taxonomy tag.
Independently verifiable today (no trust in the producer required):
- The DSSE signature and the
keyidbinding (anyone with the public key can verify the bytes). - The subject digest binding (the verdict is cryptographically tied to a specific artifact digest).
- The catch-record per-record signatures and the batch Merkle root (the host's intercept evidence is signed and the set/order of records is committed).
- Vocabulary conformance (a verifier checks every enum value against the registry version it knows).
- The value-binding anchors in the security verdict when the auditor supplies the external reference values (corpus exhaustion against the auditor's known corpus id set; substrate freshness against the auditor's approved digest). These are verifiable, but only relative to anchors the auditor brings, not from the verdict alone.
Producer self-assertions (a verifier cannot independently confirm these from the verdict alone):
- That the attack corpus contained real exploits and not no-ops - a verifier confirms the corpus digest but cannot, from the verdict alone, confirm the corpus content is adversarial. Exhaustion is checked against an auditor-supplied anchor, not asserted as a solo completeness guarantee.
- That the engine identity recorded is the engine that actually ran - pinnable and comparable against an auditor-known identity, but the verdict does not let a third party re-derive it.
- Everything an evidence-scope-disclosure carries about its own
scope - the
honest_scopeprose, theis_synthetic_fixtureflag, the coverage map, and the live-attestation posture. That predicate is built entirely out of self-assertions on purpose, and its observation table names each one. A verifier checks the shape and the internal consistency rules; nothing in it grounds a claim that the work described happened. - For the substrate/mesh predicates: that the freeze timing numbers, the captured-segment evidence, the
network-topology booleans, the hop log, and the VMA-walk access proofs were produced by a real run
rather than asserted. A verifier confirms integrity, subject binding, and internal-rule consistency
(well-formed distributions, the atomicity / bounded-pause rules, full-file-only ML-BOM identity,
auth_downgrade_causeregistration), and can chase every bound digest to its served evidence - but not external re-execution. Each substrate/mesh document states this in its own honesty section.
Roadmap (not in v1):
- A decentralized, keyless trust model (TUF / Sigstore-Fulcio) is deferred to a v2 envelope profile; v1 uses configurable public-key trust anchors.
- Cross-vendor standardization review of the wave-2 predicate families above. Their formats and offline verification are stable and published; a wave-1 verifier is not required to implement them.
- Automated, feed-driven substrate revocation (v1 uses a manually consulted VEX document).
- The forward-looking capabilities behind the substrate/mesh predicates (the egress-proxy ML-BOM
identity source, the hardware/zkVM host-trust root). The predicate formats and offline
verification are stable now; the shipped a2a-mesh-scorecard bundle binds a real sealed N=3 jailed run
(
substrate_roots_real == true,hop_graph_live == false) carrying the offline mesh evaluator's verbatim escalation verdict. The forward-looking leg is the live on-the-wire delegation observation (hop_graph_live == true), not yet shipped.
Conventions
- The key words MUST, MUST NOT, REQUIRED, SHOULD, SHOULD NOT, MAY, and OPTIONAL in every document of this standard are to be interpreted as described in RFC 2119.
- All digests are SHA-256 unless stated otherwise, encoded as 64-character lowercase hexadecimal.
- All documents and all on-wire values are ASCII or UTF-8; no document of this standard requires any non-ASCII content.