Copyright © 2026 the Contributors to the Universal Manifest Specification. This document is published under the W3C Software and Document License.
Restructured per the Conformance-Tier Stack strategy (owner-selected, audit 2026-06-11). DRAFT for review.
This is a companion profile to the Universal Manifest v0.4 Base specification. It specifies the credential-binding mechanics that turn the Base's Tier-1 requirement into running code. Read the Base first; this document assumes its terminology, envelope, and evaluation sequence.
Companion to: Base specification
(Tier-0 / Tier-1 Core). Registry categories:
binding, trust. Status:
Production-candidate normative content (carried forward and extended
from v0.3); not PREVIEW.
The Base specification requires, for any claim relied upon
at Tier 1 or above, a verified holderBinding (Base
§6.4.2, Base
§4.2), and it carries the binding field surface on claims
(Base
§1.4.3) and on receipts (Base
§3.3.1.1). This profile specifies the mechanics the Base
names:
claimProof
verification procedure.This profile is OPTIONAL to implement, but REQUIRED for any
implementation claiming Tier 1 or higher assurance (Base
§4.7). An evaluator that does not implement it records the binding
statuses as "absent" and caps every relied-upon claim at
Tier 0.
Non-goals: this profile does not define the Tier-2 cryptographic cross-DID proof (EXT-T2) or the Tier-3 ceremony (EXT-T3); it specifies the Tier-1 layer those tiers build upon.
Manifests without holderBinding on their claims MUST NOT
be treated as providing identity assurance above Tier 0, regardless of
the trust tier declared by the holder. Every claim intended to be relied
upon at Tier 1 or above MUST carry holderBinding.
The holderBinding object supports three modes:
"sd-jwt-kb" — SD-JWT Key Binding per [RFC9901]. The credential contains a
cnf (confirmation) claim ([RFC7800]) with a JWK Thumbprint ([RFC7638]) binding the credential to a specific
holder key. The cnfThumbprint field is REQUIRED when this
mode is used. This is the mandatory-to-implement
baseline."bbs-holder-commitment" — BBS+ holder binding per the
W3C Data Integrity BBS Cryptosuites. The issuer commits to a
holder-private key during credential issuance; the holder derives a
zero-knowledge proof demonstrating possession of the bound key without
revealing it. Presentations are unlinkable. The
pseudonymScope field is OPTIONAL; when present it enables
scope-exclusive pseudonyms per verifier. RECOMMENDED for
privacy-sensitive deployments."reciprocal-control" — Direct DID binding. Both the
manifest subject and the bound DID sign the same challenge (the manifest
@id). The boundDid, subjectProof,
and boundDidProof fields are REQUIRED.For each mode, the evaluator performs the following verification during Stage-2 sub-step 2a (T1.4):
sd-jwt-kb.
claimProof.cnf JWK thumbprint ([RFC7638]) equals the declared
cnfThumbprint.aud equals the presentation
audience and its nonce equals the presentation
challenge (T1.2), and
that its sd_hash covers the disclosed credential.holderBindingStatus: "failed"
and cap the claim at Tier 0.bbs-holder-commitment. The binding
carries the REQUIRED fields commitment (the issuer's
commitment to the holder secret) and proofValue (the
holder's zero-knowledge proof of possession), and the OPTIONAL
pseudonymScope ([VC-DI-BBS]).
proofValue demonstrates
possession of the secret committed in commitment, against
the issuer's BLS12-381 public key.pseudonymScope is present, confirm the pseudonym is
bound to that scope (and not reused across verifiers — T1.6.1).holderBindingStatus: "failed" and
cap the claim at Tier 0.reciprocal-control. Confirm
subjectProof and boundDidProof are each valid
signatures over the manifest @id by the manifest
subject key and the boundDid key respectively;
on failure record holderBindingStatus: "failed". (See the
limitation in T1.6.3.)
Verifying an sd-jwt-kb binding presupposes an
interactive presentation: step 4 compares the KB-JWT aud
and nonce against the audience and
challenge of the presentation (T1.2). In non-interactive contexts
(offline or cached presentation), holder binding at Tier 1 or above is
carried by the bbs-holder-commitment or
reciprocal-control modes, which verify without a
verifier-issued challenge.
The receipt field holderBindingStatus records the
outcome as one of "verified", "failed",
"unsupported-mode", or "absent" (Base
§3.3.1.1); "absent" indicates the claim carried no
holderBinding.
The presentationProof field at the manifest root
provides proof-of-possession at verification time, binding the manifest
to a specific verifier and moment. It prevents manifest replay.
When presenting a manifest in response to a verifier-issued challenge
(an interactive presentation), the presenter MUST include a
presentationProof containing:
proofType — One of "sd-jwt-kb",
"bbs-derived", or "did-auth".challenge — The verifier-issued nonce. MUST be unique
per presentation request.audience — The verifier's identifier (DID or origin).
MUST match the requesting verifier.created — RFC 3339 timestamp of proof generation.proofValue — Base64url-encoded proof (KB-JWT, BBS+
derived proof, or DID Auth signature).presentationProof is excluded from the manifest signing
input (removed alongside signature in step 2 of Base
§1.6.3). Its proofValue MUST be computed over the
concatenation of: the manifest's signing-input hash (SHA-256 of the Base
§1.6.3 canonical bytes, as its 32 raw bytes), then the UTF-8 bytes
of challenge, audience, and
created, in that order, per the mechanics of the declared
proofType (KB-JWT per [RFC9901];
BBS+ derived proof per [VC-DI-BBS]; DID Auth
signature per [DID-CORE]). Binding the proof
to the signing-input hash ties the presentation to the exact signed
manifest without requiring the holder to re-sign per presentation.
A manifest presented without a presentationProof is
valid only for offline or cached identity display, not for interactive
verification. When the evaluator itself issued a challenge for this
presentation and presentationProof is absent, the evaluator
MUST treat the manifest as replay-suspect, MUST NOT accept it for
interactive verification, and records
presentationProofStatus: "missing-required". The receipt
field presentationProofStatus is one of
"verified", "failed",
"missing-required", or "absent".
A livenessAttestation proves human presence at
attestedAt. It does not prove human
presence at verification time. Evaluators MUST NOT treat a stale
liveness attestation as equivalent to current human presence.
Four freshness classes are defined. An attestation past its
validUntil is "unknown" regardless of
attestedAt; otherwise the classes are evaluated in the
order listed and the first match applies:
"live" — Attested within 60 seconds. Suitable for
high-stakes transactions."recent" — Attested within 4 hours. Suitable for
spatial platform entry."stale" — Attested more than 4 hours ago but within the
attestation's validUntil. Evaluators SHOULD require
re-attestation for sensitive operations."unknown" — No liveness attestation present (default
for offline mode), or an attestation whose validUntil has
passed. An attestation past its validUntil MUST be treated
as "unknown".The livenessAttestation is a root-level member of the
manifest (carried among the optional credential-binding members of the
abstract data model — EXT-OPT). When present it MUST
contain proofType (a string identifying the liveness
method, e.g. "webauthn-uv"; extensible via the profile
registry — EXT-OPT),
attestedAt (RFC 3339, when human presence was attested),
validUntil (RFC 3339, after which the attestation is
"unknown"), and proofValue (Base64url-encoded;
MUST be computed over the UTF-8 bytes of the manifest
subject concatenated with the UTF-8 bytes of
attestedAt, signed by the attesting authenticator or
platform key). It MAY contain method (the authentication
method, copied into the receipt), userVerified (boolean,
copied into the receipt), and attester (the DID of the
attesting authority).
WebAuthn user-verification (a WebAuthn Level 3 [WEBAUTHN] assertion with the user-verified flag
set, proofType: "webauthn-uv") is the RECOMMENDED liveness
method. Evaluators verifying a livenessAttestation MUST
validate proofValue against the named
proofType's mechanics before treating the attestation's
freshness class as evidence of human presence. The receipt field
livenessStatus is an object containing
freshnessClass (one of "live",
"recent", "stale", "unknown")
and, when present, the method and userVerified
values copied from the attestation.
When the manifest relies on the credential-binding mechanisms of this
profile for Tier 1 or higher assurance, the evaluator MUST perform the
following sub-steps as part of the Verify stage (Base
§3.1.2). Each sub-step records its outcome in the credential-binding
receipt fields (Base
§3.3.1.1). Evaluators that do not implement credential binding skip
these sub-steps and record the corresponding statuses as
"absent".
holderBinding (T1.1), verify the binding according to
its mode. Record holderBindingStatus. A claim
relied upon for assurance whose holder binding fails or is absent MUST
NOT be granted trust above Tier 0.presentationProof (T1.2), verify that
challenge matches the verifier-issued nonce,
audience matches this verifier, and proofValue
validates over the signing-input hash, challenge,
audience, and created. Record
presentationProofStatus. A failed presentation proof MUST
cause the manifest to be treated as replay-suspect and rejected for
interactive verification. When the evaluator issued a challenge and no
presentationProof is present, the evaluator MUST treat the
absence identically to a failed proof, record
presentationProofStatus: "missing-required", and reject the
manifest for interactive verification.livenessAttestation (T1.3) is present, verify its proof
and compute its freshnessClass from
attestedAt. Record livenessStatus. Evaluators
MUST NOT treat a stale or unknown freshness
class as current human presence.identity.crossDidBinding claim (Base
§6.4.4), verify the attester authorization (when attester-asserted)
and any Tier 2 bindingProof (EXT-T2) or Tier 3
ceremonyProof (EXT-T3) per the claim-proof
process (T1.5).
Record each result in crossDidBindingStatus.These sub-steps are the normative record of how the binding mechanics weave into the evaluation sequence; the binding modes and proof procedures they invoke are defined in this profile and in EXT-T2 / EXT-T3.
This is the normative end-to-end procedure an evaluator follows to
determine whether a claim carried in a manifest is trustworthy at Tier 1
or above. It ties together the outer manifest signature verification (Base
§1.6), the claimProof field (Base
§6.4.3), and the cross-DID binding attestation (Base
§6.4.4) into a single verification chain.
claimProof
Verification ProcedureWhen claiming Tier 1 assurance or higher, the evaluator MUST perform the verification steps below; at Tier 0 these checks are OPTIONAL.
claimProof is present as an embedded
object, the evaluator MUST verify the VP proof chain: (a) the
VC signature validates to the stated issuer, (b) the VP signature
validates to the holder, (c) the holder DID matches the manifest
subject."unverified" with a reason such as
um:reason:trust:claimproof-unresolved, rather than
"verified".claimProof is an array, each
entry is independently verified; the claim is backed by the conjunction
of all valid proofs.VPs used as claimProof SHOULD include domain (audience
binding) and challenge (nonce) parameters to prevent cross-manifest
replay. Evaluators MUST enforce size limits of at most 50 KB per
embedded VP and at most 500 KB total VP payload across all claims in one
manifest, and MUST document any stricter limit in their conformance
claim.
For each claim requiring Tier 1 or higher trust, the evaluator MUST execute the following seven-step procedure:
subject DID document. Confirm that the signing
key (referenced via signature.keyRef) appears in the
subject's DID document under the authentication or
assertionMethod verification relationship, per [DID-CORE] §5.3. If the manifest signing key is
not authorized for the subject, the evaluator MUST record this as a
verification failure.claimProof, resolve the
claims[].issuer DID document per W3C DID Resolution.claimProof is present:
proofType is absent, infer
from the proof structure.verificationMethod is present, resolve the URI to
the issuer's DID document. Confirm the key appears under the
assertionMethod verification relationship. This is the
key-authorization step: it proves the signing key was authorized by the
stated issuer DID to issue credentials. (See [DID-CORE] §5.3 and [VC-DATA-MODEL] §6.)statusRef is present on the proof entry, check
revocation status per the statusRef resolution schema (EXT-OPT).claimProof is an array, each entry is independently
verified; the claim is backed by the conjunction of all valid
proofs.identity.crossDidBinding claims; skipped
when the binding carries only a cryptographic bindingProof
or ceremonyProof, whose verification is defined in EXT-T2 and EXT-T3). Resolve the
attester DID document. Confirm the attester's signing key
appears under the assertionMethod verification
relationship. Confirm the attester is on the evaluator's configurable
trust list per Base
§6.4.4.statusRef. This is distinct from the manifest-instance
status resolved via signature.statusRef. Inner key
revocation (claim-issuer and attester keys) SHOULD be checked when
revocation information is available.requiredTrustTier floors) and emit the receipt
per Base
§3.3.For each step that names a verification relationship, the evaluator MUST confirm the signing key appears under the matching W3C DID Core verification relationship:
authentication or
assertionMethod on the manifest subject's DID
document.assertionMethod on the VC issuer's DID document.assertionMethod on the attester's DID document.capabilityDelegation on the delegator's DID document (Base
§6.5).The verification chain separates two concerns that MUST NOT be conflated:
Non-normative note: OMATrust's Key Binding attestation type operationalizes the key-authorization pattern for the EVM ecosystem. UM cites W3C DID Core and VCDM 2.0 as the normative sources for the verification-relationship model.
If pseudonymScope is reused across verifiers,
cross-verifier correlation becomes possible. Issuers SHOULD generate
unique scope URIs per verifier relationship. Evaluators MUST NOT use a
shared pseudonym scope for multiple independent verifier
relationships.
Tier 2 profiles using Groth16 require a trusted setup ceremony (EXT-T2). The ceremony parameters MUST be publicly auditable. Verifiers MUST verify proofs against the published verification key, not against a key provided by the prover.
Reciprocal control (two DIDs signing the same challenge) proves the
same entity or cooperating entities control both keys. It does
not prove they are the same natural person. For
sameSubject assurance, combine reciprocal control with
issuer-attested binding (Tier 1) or linked-secret proof (Tier 2 — EXT-T2).
v0.4 evaluators encountering a v0.3 manifest (no
holderBinding, no presentationProof, no
livenessAttestation) MUST:
holderBindingStatus: "absent" in the
receipt.presentationProofStatus: "absent" in the
receipt.livenessStatus.freshnessClass: "unknown" in the
receipt.requiredTrustTier declarations.A v0.3 manifest that declares no manifest-level
requiredTrustTier (or declares Tier 0) is accepted but
flagged as "unbound" at Tier 0; evaluators decide their own policy for
unbound manifests. Where a v0.3 manifest declares a manifest-level
requiredTrustTier that cannot be satisfied because binding
material is absent, Base
§6.4.5 governs the outcome: the manifest is processed with outcome
rejected for trust-gated use, or
accepted-with-warnings for display-only use, per local
policy. Capping the effective trust tier at Tier 0 (step 5) does not by
itself reject the manifest; the declared floor does.
v0.4 evaluators SHOULD emit an
um:reason:trust:unbound-claims warning in the receipt when
processing manifests without holder binding. (Worked example:
unbound-claims warning — see Cookbook.)
Cited in this profile (full descriptors in the published artifact):
cnf).Companion to the Base specification. For Tier-2 cryptographic binding, see EXT-T2. For worked examples, see the Cookbook.