| Internet-Draft | SCITT Composite Verification | July 2026 |
| Aoki | Expires 8 January 2027 | [Page] |
This document defines a common model for composite verification of SCITT statement graphs. A composite verifier checks a set of SCITT Signed Statements, receipts, object bindings, and relationship edges under a named verification profile. The result is a structured report that can say which statements passed, which evidence is missing, which evidence is stale, and which statements conflict.¶
The model is intended for verifiers, auditors, deployment controllers, update services, and other relying-party tools. It is not a new Transparency Service requirement. It does not define a universal supply-chain policy language and does not define the payload format of any statement type.¶
This note is to be removed before publishing as an RFC.¶
The latest revision of this draft can be found at https://aoki-n1.github.io/draft-nobuo-scitt-composite-evidence-verification/draft-nobuo-scitt-composite-evidence-verification.html. Status information for this document may be found at https://datatracker.ietf.org/doc/draft-nobuo-scitt-composite-evidence-verification/.¶
Discussion of this document takes place on the SCITT Working Group mailing list (mailto:scitt@ietf.org), which is archived at https://mailarchive.ietf.org/arch/browse/scitt/. Subscribe at https://www.ietf.org/mailman/listinfo/scitt/.¶
Source for this draft and an issue tracker can be found at https://github.com/aoki-n1/draft-nobuo-scitt-composite-evidence-verification.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 8 January 2027.¶
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
SCITT lets a consumer verify that a signed statement was registered in a Transparency Service. Many real decisions need a larger evidence set. A consumer may need to check that a firmware SBOM describes the firmware measured on a device, that an update authorization covers that firmware, that an attestation result was issued by an acceptable verifier, and that no accepted statement revokes or conflicts with the set.¶
Without a common composite verification model, each ecosystem defines its own API, result terms, freshness checks, conflict handling, and evidence bundle format. This can lead to tools that cannot work together even when the individual SCITT statements and receipts are valid.¶
This document defines an information model and an optional HTTP binding for composite verification. The model is intentionally small. It provides common request and result fields while leaving domain policy to profiles.¶
The composite verifier can be local software, a remote service, an auditor tool, a deployment controller, or a supply-chain risk engine. It does not have to be the same component as the SCITT Transparency Service.¶
This draft is based on the observation that SCITT can register many statements about the same subject, but the basic registration path is not a full graph query system. IETF 122 discussion noted support for multiple vendors or organizations making statements about an artifact, and also raised the pattern of "statements about statements". The same discussion noted that reliable locators can be used as pointers.¶
IETF 124 discussion raised the question of whether graph information belongs in payloads, COSE headers, or later auxiliary services. It also noted that SCRAPI does not currently provide an API for graph work, and that adding such support directly to SCRAPI would be a larger effort.¶
This draft therefore treats composite verification as a verifier or auditor function. It can use SCITT statements, receipts, locators, and graph manifests, but it does not require the Transparency Service to make composite decisions.¶
The goals of this profile are to:¶
allow a requester to identify the subject of verification;¶
allow evidence to be provided by value, by reference, or by graph manifest;¶
allow the requester or profile to name required statement types;¶
express issuer, relationship, freshness, and conflict constraints;¶
return clear result values for pass, fail, warning, unknown, missing, stale, and conflict cases;¶
support online and offline verification;¶
allow evidence bundles to move between tools; and¶
avoid defining the truth conditions of domain-specific payloads.¶
This profile does not:¶
define a universal policy language;¶
require a Transparency Service to perform composite verification;¶
require the SCITT Reference API to support graph discovery;¶
require a verifier to fetch all evidence automatically;¶
decide whether a payload claim is true;¶
define SBOM, HBOM, CBOM, VEX, attestation, vulnerability, or audit schemas;¶
define best practices for software, hardware, cloud, or IoT supply-chain design; or¶
replace SCITT statement and receipt verification.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
This document imports the terms Protected Object, Statement Reference, Receipt Reference, Relationship Edge, and Statement Graph from [I-D.nobuo-scitt-protected-object-binding].¶
The evaluation of several SCITT statements, receipts, object bindings, and relationship edges under a selected verification profile.¶
A named set of rules that tells a verifier which statement types, issuers, relations, freshness limits, and conflict rules apply.¶
A request that identifies a subject, a verification profile, optional evidence, and optional constraints.¶
A result object that reports the outcome of composite verification.¶
A portable package that contains statements, receipts, graph manifests, and policy identifiers needed for composite verification.¶
A short code that states the result for the whole verification or for one part of the evidence graph.¶
A Transparency Service should be able to stay small. Its core job is to accept a signed statement under a registration policy and return a receipt. Composite verification is different. It applies a relying-party policy to a graph of evidence.¶
For this reason, a conforming Transparency Service is not required to implement the interface in this document. Deployments can implement composite verification in one of the following places:¶
a local verifier;¶
a remote verification service;¶
an auditor tool;¶
a deployment controller;¶
an update service;¶
a compliance system; or¶
an auxiliary service next to SCRAPI.¶
This split keeps the SCITT registration path simple while still allowing ecosystems to exchange and verify graph-level evidence.¶
Composite verification runs over a Statement Graph. The graph can be supplied in a Statement Graph Manifest, as separate references, or through another profile-defined package.¶
A verifier performs four kinds of checks:¶
Statement checks: signature, syntax, profile, and optional payload checks.¶
Receipt checks: receipt profile, inclusion proof, and registration data.¶
Graph checks: object binding, required relationships, conflicts, supersession, revocation, and dependency edges.¶
Policy checks: issuer rules, freshness rules, required statement types, and domain-specific acceptance rules.¶
The verifier MUST verify all individual statements and receipts required by the
selected profile before it returns pass for the whole graph.¶
A verifier MUST NOT claim that a payload is true only because it is signed and registered. A registered false statement can still be false. Composite verification only reports that the evidence set satisfies the selected verification profile.¶
Composite verification can use statements that refer to other statements. This is needed when the evidence set has history.¶
Examples include:¶
an audit statement about a submitted statement;¶
a fix statement that answers a vulnerability statement;¶
a supersession statement that marks a newer SBOM as current;¶
a revocation statement;¶
a failed-build statement that records why a build chain did not complete; and¶
a graph manifest statement that records a selected evidence set.¶
A verifier MUST treat these as ordinary SCITT statements. It MUST verify their signatures and receipts before using them. It MUST also apply policy to decide whether the issuer is allowed to assert the relation.¶
A Verification Request identifies the subject and the verification profile. A request MAY include evidence directly or by reference.¶
; This CDDL is provisional and needs WG review.
verification-request = {
subject: node-reference,
verification_profile: tstr,
? evidence: evidence-input,
? required_statement_types: [+ tstr],
? accepted_issuers: {+ tstr => [+ tstr]},
? freshness: {+ tstr => duration},
? relationship_requirements: [+ relationship-requirement],
? conflict_policy: conflict-policy,
? result_options: result-options,
? nonce: bytes,
? request_id: tstr
}
node-reference = tstr / {
? object: any,
? statement: any,
? id: tstr
}
evidence-input = {
? statements: [+ any],
? receipts: [+ any],
? graph_manifest: any,
? embedded_bundle: evidence-bundle,
? evidence_locations: [+ tstr]
}
relationship-requirement = {
from_type: tstr,
relation: tstr,
to_type: tstr,
? required: bool
}
conflict-policy = "fail" / "warn" / "ignore" / tstr
result-options = {
? include_graph: bool,
? include_statement_results: bool,
? include_receipt_results: bool,
? include_missing_evidence: bool,
? include_conflicts: bool,
? include_warnings: bool
}
duration = tstr
¶
The verification_profile field names the policy family to apply. A profile
can be general, such as scitt-basic-graph/v1, or domain specific, such as
iot-device-runtime-integrity/v1.¶
The accepted_issuers field is a constraint supplied by the requester or by a
higher-level profile. This document does not define a global list of trusted
issuers.¶
The freshness field contains duration strings. TODO: decide whether this
document should normatively use an existing duration syntax or define a small
CBOR-native form.¶
Composite verification cannot assume that the submitted evidence set is complete. A presenter may omit a conflicting statement, an old revocation, or a newer superseding statement. A verifier therefore needs a policy for evidence coverage.¶
A verification profile SHOULD state at least:¶
which statement types are required;¶
which issuers or issuer roles are accepted for each type;¶
whether the verifier must search for newer or conflicting statements;¶
which locators or auxiliary services may be used for discovery;¶
how old evidence may be before it becomes stale; and¶
how to report a result when the verifier cannot check completeness.¶
When a verifier cannot check completeness, it SHOULD return unknown or
warning instead of pass, unless the selected profile allows closed-world
verification over the supplied bundle.¶
An Evidence Bundle packages the evidence needed for offline or asynchronous verification.¶
; This CDDL is provisional and needs WG review.
evidence-bundle = {
bundle_type: "scitt-evidence-bundle/v1",
subject: node-reference,
? profile: tstr,
? statements: [+ any],
? receipts: [+ any],
? graph_manifest: any,
? related_bundles: [+ digest],
? created_at: time,
? expires_at: time,
? bundle_digest: digest,
? attributes: {* tstr => any}
}
digest = {
alg: tstr,
value: bytes
}
¶
A bundle can be used when the verifier cannot reach the original Transparency Service during evaluation. A verifier using a bundle MUST still verify the statements and receipts inside the bundle.¶
A Verification Result reports the outcome of the composite check.¶
; This CDDL is provisional and needs WG review.
verification-result = {
subject: node-reference,
verification_profile: tstr,
overall_result: result-code,
? request_id: tstr,
? verified_statements: [+ statement-result],
? receipt_results: [+ receipt-result],
? missing_evidence: [+ missing-evidence],
? conflicts: [+ conflict-result],
? warnings: [+ warning-result],
? graph_digest: digest,
? evaluated_at: time,
? verifier: tstr,
? attributes: {* tstr => any}
}
result-code = "pass" / "fail" / "warning" / "unknown" /
"missing" / "stale" / "conflict" / "not-applicable" /
tstr
statement-result = {
statement: any,
result: result-code,
? issuer: tstr,
? statement_type: tstr,
? errors: [+ tstr],
? warnings: [+ tstr]
}
receipt-result = {
receipt: any,
result: result-code,
? errors: [+ tstr],
? warnings: [+ tstr]
}
missing-evidence = {
evidence_type: tstr,
? relation: tstr,
? expected_issuer_role: tstr,
? message: tstr
}
conflict-result = {
conflict_type: tstr,
nodes: [+ tstr],
? message: tstr
}
warning-result = {
warning_type: tstr,
? node: tstr,
? message: tstr
}
¶
A verifier SHOULD use the following meanings:¶
The evidence satisfies the selected verification profile.¶
The evidence does not satisfy the selected verification profile.¶
The evidence satisfies mandatory checks, but the verifier found a condition that should be shown to the relying party.¶
The verifier could not reach a decision. This can happen when evidence is unavailable or when a profile is not understood.¶
Required evidence is missing.¶
Evidence is older than the freshness rule allows.¶
The graph contains statements or edges that conflict under the selected profile.¶
A rule was not applicable to the subject or profile.¶
TODO: Decide whether these result codes should be registered with IANA.¶
The following example is illustrative only.¶
{
"subject": {
"object": {
"object_type": "device-instance",
"object_id": "urn:example:device:gateway-1234"
}
},
"verification_profile": "iot-device-runtime-integrity/v1",
"required_statement_types": [
"device-identity",
"firmware-sbom",
"firmware-update-authorization",
"rats-attestation-result",
"vulnerability-status"
],
"accepted_issuers": {
"device-identity": ["manufacturer"],
"firmware-update-authorization": ["device-operator", "manufacturer"],
"rats-attestation-result": ["trusted-verifier"],
"vulnerability-status": ["vendor", "authorized-third-party"]
},
"freshness": {
"rats-attestation-result": "PT24H",
"vulnerability-status": "P7D"
},
"relationship_requirements": [
{
"from_type": "firmware-sbom",
"relation": "describes",
"to_type": "firmware-image",
"required": true
},
{
"from_type": "rats-attestation-result",
"relation": "measures",
"to_type": "device-instance",
"required": true
}
],
"conflict_policy": "fail"
}
¶
This document defines an optional HTTP binding for deployments that want a remote composite verifier. The binding is not a Transparency Service requirement.¶
POST /scitt/composite-verifications HTTP/1.1 Content-Type: application/scitt-composite-verification-request+cbor Accept: application/scitt-composite-verification-result+cbor¶
The response body is a verification-result.¶
A server MAY also support JSON media types for debugging or deployment convenience:¶
application/scitt-composite-verification-request+json¶
application/scitt-composite-verification-result+json¶
TODO: Decide whether the HTTP binding belongs in this document, in a separate binding document, or only in examples.¶
Composite verification may be run long after the original statements were
registered. It may also be run while some evidence is still pending. A profile
should not assume that a POST to a Transparency Service always returns a final
receipt synchronously.¶
A verifier or auxiliary service can encounter:¶
a statement reference with no receipt yet;¶
a resource that has moved to a different locator;¶
a failed registration;¶
a sharded service that returns a different status location; or¶
a bundle that was prepared before all related statements were available.¶
The result model in this document can represent these cases with unknown,
missing, stale, warning, or a profile-defined result code.¶
Some evidence sets can require network retrieval, large receipts, external policy checks, or manual audit review. A composite verifier MAY support an asynchronous mode.¶
In asynchronous mode, the initial response can return a status resource. The
final result MUST be the same verification-result structure used by the
synchronous mode.¶
TODO: Define status codes, retry handling, cancellation, and expiry rules if the WG decides to include asynchronous behavior.¶
Composite verification can reveal more information than single-statement verification because graph edges show relationships among devices, software, services, cloud tenants, suppliers, and auditors.¶
A requester SHOULD provide only the evidence needed for the selected profile. A verifier SHOULD avoid returning more graph detail than the requester asked for. Profiles MAY use encrypted statements, salted identifiers, selective disclosure, or access-controlled evidence bundles.¶
A verifier that stores requests or results can become a sensitive data store. Deployments SHOULD define retention and access-control rules.¶
Composite verification depends on the integrity of every required statement, receipt, and edge.¶
Implementations MUST verify the relevant signatures and receipts before making a
pass decision. Implementations MUST apply issuer authorization rules for each
statement type and relation.¶
Risks include:¶
accepting a graph with missing evidence;¶
accepting a stale attestation or vulnerability statement;¶
accepting a relation asserted by an unauthorized issuer;¶
hiding a conflicting statement;¶
mixing evidence about two different objects;¶
confusing statement freshness with object freshness;¶
returning a pass result for an unsupported profile; and¶
leaking sensitive graph information through result details.¶
TODO: Add detailed error priority rules. For example, invalid receipt should
probably take precedence over freshness warnings, while unsupported policy may
return unknown instead of fail.¶
This document requests no IANA action yet.¶
TODO: Consider IANA registrations for:¶
This revision treats composite verification as an auxiliary verifier function, not as an extension to the core Transparency Service. This follows the concern that adding graph discovery to the basic registry API could make that API much larger.¶
The IETF 122 discussion is reflected in this draft in three ways. First, the model allows more than one organization to make statements about the same subject. Second, the model allows statements about statements, which can help when a later statement fixes, updates, audits, or explains an earlier statement. Third, the model allows evidence to be identified by stable locators, so that a verifier can build a graph without requiring the Transparency Service itself to become a graph database.¶
The IETF 124 discussion is reflected by keeping graph discovery and composite verification outside the mandatory SCRAPI registration path. The draft leaves open whether future profiles place graph hints in payloads, protected metadata, separate graph manifests, or auxiliary services.¶
The author thanks the SCITT WG participants for discussions on graph building, opaque payloads, receipt verification, and hardware and software evidence. The IETF 124 discussion was useful in separating the core registry function from possible auxiliary graph and verification services.¶