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 collects the capabilities that are not rungs on the trust-tier ladder but are independently optional — features a conformance claim adds orthogonally to its tier. Read the Base first; this document assumes its terminology, envelope, and evaluation sequence.
Each part below is self-contained. The Base names each of these features and points here; nothing in this document changes the Tier-0/Tier-1 conformance surface. Parts marked PREVIEW are under working-group review and revisable before the schema locks.
Companion to: Base specification
(Tier-0 / Tier-1 Core). Registry categories: spans
domain, signature, and others (per
feature).
trustWeight
PREVIEWThe Base names the abstract data model and treats JSON-LD as the reference encoding; this part specifies the model in full, the production-rule contract, the CBOR-LD compact encoding, and the conformance and context-integrity production details.
A Universal Manifest is defined in two layers. The abstract data model specifies the manifest's types, properties, and semantics independently of any serialization. A production rule specifies how that abstract model is written into — and read back from — a concrete wire format. This separation, modeled on W3C DID Core [DID-CORE], lets the manifest gain new encodings without changing what a manifest means. Member definitions and examples are presented in the JSON-LD reference encoding as an editorial convenience, not a normative restriction: every requirement stated in terms of a JSON-LD member applies to the corresponding abstract property in any conformant encoding.
The abstract data model describes a manifest as a map of abstract properties to values, using the format-agnostic core data types of [INFRA]. The abstract properties constituting a Universal Manifest (each production rule defines how a name is expressed in its format):
um:Manifest. Expressed as @type in
JSON-LD.@id.@context in JSON-LD; carried as a compression context
reference in CBOR-LD.The semantics of these properties — the evaluation sequence, the tiered trust model, consent matching, signature verification, and all conformance obligations — are defined against this abstract data model and do not depend on which production rule serialized a given manifest. Extensions and future versions that define new root-level members MUST define them as abstract properties with a representation in each production rule they are used with; unknown members are preserved as unprocessed entries. The integrity proof is computed over the bytes of a specific production (O1.5), so a signature is bound to one encoding: converting a signed manifest between encodings requires re-signing; the meaning is preserved across encodings, the signature bytes are not.
A production rule is a bidirectional mapping between the abstract data model and a concrete byte representation. Production serializes; consumption parses back. A production rule MUST: (1) define a media type identifying the encoding; (2) specify how each abstract property is represented, including required and optional properties; (3) guarantee that consumption of a produced representation yields an abstract manifest equal to the original (lossless round-trip) for all properties defined by this specification. This specification defines two production rules: JSON-LD (reference) and CBOR-LD (compact). Future versions or profiles MAY define additional production rules (e.g., plain-JSON or COSE-based) without altering the abstract data model. Evaluators MUST NOT assume the absence of a production rule from this list means a manifest is non-conformant; they reject representations whose media type or encoding they do not support, exactly as they reject unsupported signature profiles.
The JSON-LD production rule is the reference encoding and the default
for interoperation. A manifest in this encoding is a JSON-LD document
[JSON-LD] as described in Base
§1.2–§1.6.
Media type application/um+ld+json (also valid
application/ld+json). The mapping is direct: abstract
type, id,
contextReference → @type,
@id, @context; all other abstract properties →
JSON members of the same name; abstract datetimes → RFC 3339 strings;
integers/strings/lists/maps → JSON counterparts. A lone
@context string is consumed as a one-element
contextReference list; producers SHOULD emit the array form
(normalization does not affect the signature, which covers the concrete
bytes of the consumed production).
The CBOR-LD production rule is a second, compact binary encoding
defined to demonstrate that the abstract data model is genuinely
format-independent. It targets constrained channels — QR codes, NFC
tags, low-bandwidth/embedded transports — where JSON-LD verbosity is
costly. Media type application/um+cbor-ld. CBOR-LD [CBOR-LD] compresses a JSON-LD document into CBOR
[RFC8949] by using the manifest's JSON-LD
context to replace string term names with compact integer tokens:
This mapping is bidirectional and semantically lossless for all abstract properties: a manifest produced in CBOR-LD and then consumed MUST yield the same abstract manifest as the JSON-LD production from which it was derived. Conformance is identical across the two encodings; only the bytes on the wire differ. CBOR-LD decoding requires the manifest's context to be available to the decoder; deployments on offline or constrained channels SHOULD pre-provision the context for the relevant version, since it cannot be assumed retrievable at decode time. Term tokenization is deterministic only when both parties use the same context version, which the versioned namespace makes explicit.
Preview: A complete CBOR-LD profile — registered context-to-token table, a fixed signature production for the binary encoding (O1.5), and conformance fixtures — will be finalized after working-group review. Input is requested on whether CBOR-LD is the right compact encoding to standardize first.
The integrity proof is computed over the canonical bytes of a specific production. Signature Profile A (Base §1.6) is defined against the JSON-LD production: the signing input is the JCS-canonicalized JSON-LD document with the signing-input exclusions removed (the signature property and, when present, presentationProof and postQuantumSignature). Each production rule MUST either reuse a profile defined against the abstract model or specify how the integrity proof is computed over its own canonical bytes, so a verifier can recompute the signing input deterministically. Because a signature is bound to the bytes of one production, a manifest re-encoded under a different production rule MUST be re-signed under that production's signing rule. (Working-group note: whether a future profile should sign a canonicalization of the abstract model — making one signature portable across encodings — is the strategic open question of the format-independence design; this draft builds in per-production signing.)
The behavioral requirements of Base §4.1–§4.3 are stated against the abstract data model and apply identically regardless of encoding. A conformant implementation MUST support at least one production rule and SHOULD support the JSON-LD reference encoding; MUST consume supported representations into the abstract data model before applying behavioral requirements; MUST reject an unsupported encoding rather than misinterpreting it; MUST preserve every abstract property across a production/consumption round-trip when it both produces and consumes an encoding; and MUST verify the integrity proof against the bytes of the production it consumed. Supporting only the JSON-LD reference encoding is sufficient for full conformance; supporting CBOR-LD is OPTIONAL.
Term meanings — and, for CBOR-LD, tokenization — depend on the content of the versioned namespace context. The manifest signature covers the context reference (the URI string), not the context document content: if the served context changes or an attacker controls its resolution, term semantics and CBOR-LD round-trips can change silently under a still-valid signature. To prevent this, the versioned namespace URI identifies an immutable context: once published, the context document for a version MUST NOT change. Evaluators SHOULD ship or pin the context for each supported version rather than fetching it at evaluation time, and MUST NOT fetch contexts from untrusted resolvers at verification time. CBOR-LD deployments MUST use the pinned context, since tokenization correctness depends on byte-identical context versions on both sides. (The Base states the evaluator-facing requirement in Base §6.10; this is the production/encoding detail.)
This part specifies the resolution protocol for the
signature.statusRef field (Base
§1.6.6, Base
§3.4). signature.statusRef resolves the status of the
manifest instance identified by
manifestId; it does not convey the
revocation status of any key (key revocation is determined separately
via the key's DID document verification-method state, or a
claimProof entry's own statusRef). These
distinct objects of revocation MUST NOT be conflated.
When signature.statusRef is present and the evaluator
implements revocation-aware verification, the evaluator MUST: (1) issue
an HTTP GET to the statusRef URI; (2) if it
has a cached response, SHOULD include its most recently stored
cursor in an If-None-Match header (subject to
the revocationCursor floor below); (3) the status endpoint
MUST respond with content type application/json; (4) the
evaluator MUST parse the response and evaluate the status
field. statusRef URIs MUST use https; status
responses carry no independent signature, so authenticated transport is
the only integrity protection — evaluators MUST NOT resolve a
statusRef over plaintext and MUST treat a non-HTTPS
statusRef as unreachable. Status endpoints SHOULD return an
ETag equal to the current cursor; a
304 Not Modified means status is unchanged. The
holder-embedded signature.revocationCursor is the
issuance-time floor: an evaluator whose cached response is older than
revocationCursor MUST revalidate, and the response
cursor supersedes it thereafter.
A status endpoint MUST return a JSON object with
manifestId (MUST match the manifest's @id),
status (one of "active",
"revoked", "suspended"; MUST be present), and
updatedAt (RFC 3339; MUST be present). It MAY include
reason (human-readable), cursor (opaque;
evaluators SHOULD store for conditional requests), and
nextCheck (an ISO 8601 duration, e.g. "PT1H",
recommending when to next poll; evaluators SHOULD respect it).
"active" — signature and credentials remain valid; the
evaluator MUST continue evaluation."revoked" — permanently invalidated by the holder; the
evaluator MUST reject with outcome "rejected" and
revocationStatus: "revoked"."suspended" — temporarily suspended; the evaluator
SHOULD treat as "accepted-with-warnings" and record
revocationStatus: "suspended"; MAY apply local policy on
whether to process.When the status endpoint is unreachable or errors, evaluators MUST:
on 404, record
revocationStatus: "unchecked" with reason
um:reason:status:endpoint-unknown-manifest; on 503
or network failure, record "unchecked" with reason
um:reason:status:endpoint-unavailable and MUST NOT reject
the manifest solely because the endpoint is unreachable; on
other 4xx/5xx, record "unchecked" with the
HTTP status code in the reason. Evaluators in offline mode MUST record
"unchecked" with reason
um:reason:status:offline. Deployments MAY use a W3C
Bitstring Status List endpoint [VC-STATUS] as
the statusRef target, provided the evaluator can parse the
response into the status semantics above; this is a SHOULD-level
alternative that mitigates the status-resolution correlation risk (O5 and the privacy considerations in EXT-T2
§T2.2.1).
A conformant status endpoint (Base
§4.6) MUST respond with the response schema and status semantics
above (including the status values and the
cursor/nextCheck fields), MUST key its
response to the manifestId queried, and SHOULD support
conditional requests. Resolver conformance (the federated-status class
of O5) is deferred pending the
working-group decision on whether federation moves to a companion
specification.
(Worked example: statusRef response — see Cookbook.)
A receipt is itself a first-class manifest class (Base
§1.0.1, Base
§3.3.2): a signed, portable record that can be chained, retained,
and independently verified, carrying the common envelope members with
@type including both um:Manifest and
um:Receipt, plus the receipt fields of Base
§3.3.1. This promotion is additive; an evaluator that only emits
inline receipts remains conformant, and the chain-integrity members are
OPTIONAL unless a receipt is part of a sequence.
Receipts in a session or audit sequence form a hash-linked chain. A
chained receipt MUST include chainId (a URI identifying the
chain; for a bilateral session it MUST equal the sessionId
of O4; it is the stable
identifier tying a sequence together — exchangeId is per
exchange round and does not serve this purpose), seq (a
monotonically increasing non-negative integer; the first receipt has
seq 0), and prevHash (the hash of the
immediately preceding receipt's canonical signing bytes, encoded as a
multibase/multihash string [MULTIFORMATS]; the
multihash function MUST be SHA-256 for v0.4; omitted for
seq 0).
A chained receipt SHOULD be signed with a session-scoped
signing key (for example,
deviceCapability.sessionSigningKey of O9.2, or another ephemeral
key bound to the session) rather than a long-lived identity key, so a
receipt chain does not become a long-lived correlator. Because a
session-scoped key cannot be authorized through the subject's DID
document the way EXT-T1
§T1.5 authorizes manifest-signing keys, a session-scoped
receipt-signing key MUST be introduced by a
sessionKeyAuthorization — a statement naming the session
key, the chainId, and a validity window, signed by a key
authorized for the evaluator's DID — carried in or referenced from the
first receipt, so the chain is attributable to a known evaluator.
Evaluators verifying a chain MUST confirm each seq
increments by one without gaps and each prevHash matches
the prior receipt; a broken link MUST be reported and the chain after
the break treated as unverified.
A receipt manifest MAY carry an events array recording
typed lifecycle events. Each event object MUST carry an
eventType from the registry below and an at
(RFC 3339) timestamp; it MAY carry an event-specific reason
(O3.3) and a
subjectRef identifying the affected facet, claim, consent,
or device. Recognized event classes: manifest-arrived,
manifest-verified, manifest-rejected (envelope
lifecycle); facet-processed, facet-sealed,
facet-consent-denied (facet outcomes);
consent-granted, consent-withdrawn,
consent-expired (consent transitions);
claim-verified, claim-failed,
binding-verified, binding-failed (trust
outcomes); avatar-retrieved,
avatar-substituted (presence/avatar disclosure outcomes;
presence is a locator, not authorization);
session-completed (session terminal event). This is a
registry, not a closed enumeration: new classes are added through the
profile registration mechanism (O6). Evaluators
encountering an unrecognized eventType MUST preserve the
event but MUST NOT act on it.
Receipt reason values (on facet statuses, consent
statuses, and events) SHOULD be drawn from a structured reason registry
using um:reason:<category>:<code> naming (for
example um:reason:consent:withdrawn,
um:reason:crypto:no-decryption-key,
um:reason:trust:tier-unsupported). Structured reasons make
receipts machine-comparable. Free-text reasons remain valid where no
registry code applies. New reason codes are registered through the
profile registration mechanism (O6).
A receipt manifest MAY be anchored to an append-only transparency log
following the Certificate Transparency 2.0 model [RFC9162]. When anchored, the receipt MAY carry a
transparencyAnchor object with logId,
inclusionProof (a Merkle inclusion proof), and
anchoredAt (RFC 3339). Anchoring is OPTIONAL and does not
increase per-event cost for deployments that do not use it; it provides
tamper-evident, independently auditable history. Evaluators that do not
implement transparency anchoring MUST preserve the
transparencyAnchor field without acting on it.
(Worked example: chained receipt manifest with typed events — see Cookbook.)
Preview: Promoting the Receipt to a first-class
class — with the seq/prevHash chain, typed
event vocabulary, structured reason registry, and optional CT-style
anchoring — is built on the editors' default (promote in v0.4;
additive). Input is requested on the canonical event-class and
reason-code registries and on the hash/multibase encoding for
prevHash.
This part specifies the protocol-layer session model for bilateral exchanges, extending the manifest-level bilateral exchange of Base §6.4.6 with session objects, paired receipt correlation, and exchange identifiers.
A bilateral session is a time-bounded interaction between two
participants who each present and evaluate the other's manifest. A
session object MUST contain @type
("um:BilateralSession"), sessionId (a globally
unique URI; MUST be present), exchangeId (a correlation
identifier shared by both parties in a single exchange round; both
include the same exchangeId in their receipts; MUST be
present), participants (an array of exactly two participant
objects, each with a did and role ∈
{"initiator", "responder"}),
initiatedAt (RFC 3339), expiresAt (RFC 3339;
evaluators MUST reject session operations after this time), and
state. A session comprises exactly one exchange round; a
new exchange between the same parties is a new session with new
sessionId/exchangeId. sessionId
and exchangeId MUST each be generated with at least 128
bits of entropy and MUST NOT encode party identifiers, since both are
correlation tokens the parties rely on.
States, strictly forward (no return to a previous state):
"initiated" (initiator created the session and sent
sessionId/exchangeId);
"manifests-exchanged" (both presented manifests; each
SHOULD reference exchangeId in its presentation context);
"receipts-exchanged" (both produced and shared receipts;
each receipt MUST include exchangeId);
"completed" (both acknowledged the other's receipt);
"expired" (TTL elapsed without "completed";
evaluators MUST treat as terminated). "expired" MAY be
entered from any active state.
A receipt produced as part of a bilateral session MUST include an
exchangeId matching the session's, enabling pairing: Party
A's receipt (evaluating B's manifest) correlates with Party B's receipt
(evaluating A's manifest) via the shared identifier. A receipt exchanged
in a bilateral session MUST include evaluatorId and SHOULD
carry receiptSignature, so the exchanged receipts are
attributable and tamper-evident.
The session model is transport-agnostic. Sessions MAY be conducted over any transport that can carry manifest payloads in a supported production rule — JSON-LD or (once finalized) CBOR-LD on constrained channels: local transports (NFC, BLE, QR scan), network transports (HTTPS, WebSocket), or hybrids. Transport-specific bindings MAY be defined in profile documents. The session object MUST NOT assume any specific transport capability.
(Worked example: bilateral session object — see Cookbook.)
Note (working-group): Whether the session model remains in the core specification or is published as a separate companion specification is open; bilateral sessions are protocol-layer concerns that may evolve independently of the manifest format.
This part specifies the federation model: how multiple resolver operators coordinate to provide status checks, cache invalidation, and availability across a distributed network.
Resolver coordination. A federated resolver network
consists of two or more resolver operators that synchronize manifest
status. Resolvers MUST identify themselves using DIDs and MUST establish
mutual trust through bilateral attestation (each attests to the other's
identity via an identity.crossDidBinding claim or
equivalent). Resolver discovery is out of scope; deployments MAY use a
well-known URI (/.well-known/um-resolvers), a DID service
endpoint, or out-of-band configuration.
Status check distribution. When an evaluator
resolves a statusRef URI, it MAY query multiple federated
resolvers. If any resolver reports "revoked", the evaluator
MUST treat the manifest as revoked (revocation is authoritative and
overrides other responses). If resolvers disagree, the evaluator MUST
act on the most restrictive status received and SHOULD record a warning
with reason um:reason:status:federation-inconsistent; the
recorded revocationStatus reflects the most restrictive
answer received, not "unchecked". If all queried resolvers
are unreachable, follow the error handling in O2.4.
Cache invalidation. When a manifest's status
changes, the issuing resolver MUST propagate the change to all federated
resolvers; the federation SHOULD achieve propagation within 60 seconds
for revocation events. During the propagation window, different
evaluators may receive different answers. Evaluators SHOULD treat cached
status as provisional and re-check per nextCheck.
Availability and failover. The federation uses
eventual consistency. Evaluators MAY query any federated resolver, not
only the primary statusRef endpoint; if the primary is
unavailable, the evaluator SHOULD fall back to alternative resolvers
discovered through the federation. In split-brain scenarios, the
recorded revocationStatus reflects the most restrictive
answer actually received from any reachable resolver, with a
um:reason:status:federation-inconsistent warning;
"unchecked" is reserved for the case where no
resolver returned an answer.
Manifest forwarding. When a manifest is forwarded
across federation boundaries, the forwarding agent MUST preserve all
fields (unknown fields survive the evaluation sequence). Forwarding
metadata MUST NOT be added to the manifest payload, because the
payload's bytes are covered by the signature; a forwarding agent MAY
convey a forwardedVia array (resolver DIDs in path order)
in transport-level metadata or a wrapper object that carries the
manifest unmodified — such metadata is informational and MUST NOT affect
evaluation. Forwarded manifests MUST be re-verified by the receiving
evaluator; the forwarding agent's handling does not substitute for the
receiver's own evaluation.
Note (working-group): Whether federation should be published as a separate companion specification is open; it introduces protocol-layer complexity that may evolve independently of the manifest format.
This part defines the formal registration process for new cryptographic, trust, and domain profiles that extend the Universal Manifest specification, following IANA-style registry conventions. It is the mechanism the Base §5 extension model relies on.
Profile identification. Each registered profile MUST
have a canonical identifier following
um:profile:<category>:<name>. Categories:
signature (e.g.,
um:profile:signature:jcs-ed25519), trust
(e.g., um:profile:trust:zkp-bbs-linked-secret),
domain (domain-specific manifest class profiles, e.g.,
um:profile:domain:receipt), binding
(credential binding profiles, e.g.,
um:profile:binding:sd-jwt-kb). Each identifier MUST be
paired with a human-readable name and version string; identifiers are
globally unique and MUST NOT be reused after deprecation. This process
also governs the subsidiary value registries referenced elsewhere:
receipt event classes (O3.2),
receipt reason codes (O3.3), agent-delegation scope
values (O7), liveness
proofType values (EXT-T1
§T1.3), and additional JWE algorithm pairs (Base
§2.4).
Registration process (five steps). (1) Proposal — a profile author submits a specification to the working group via the [UM-RFC] mechanism, including a scope statement, normative requirements (RFC 2119 keywords), security considerations, an interoperability assessment, and at least one conformance test fixture. (2) Review — the working group reviews for completeness, security, and interoperability, and MUST verify the profile does not conflict with existing profiles at the same extension point. (3) Conformance integration — the author provides fixtures; the working group integrates them into the conformance suite. (4) Registration — upon consensus, the profile receives its canonical identifier and is added to the registry. (5) Maintenance — the author maintains the spec and tests; the working group MAY deprecate the profile if maintenance lapses, security issues arise, or a superseding profile is registered.
Conflict resolution. Two profiles defining
incompatible semantics for the same extension point MUST NOT both be
registered without resolution; the working group MUST resolve by
merging, selecting one, or defining a compatibility boundary.
Deprecation. The working group MAY mark a profile
"deprecated" (with a date and superseding-profile
reference); evaluators SHOULD warn on deprecated-profile references but
MUST NOT reject manifests solely for referencing one until the profile
is declared "sunset" at a major-version boundary.
Registry hosting. The registry MUST be published as a
standalone document at
https://universalmanifest.net/registry/profiles/, updated
independently of the specification version; each entry contains the
identifier, name, version, status ("active",
"deprecated", "sunset"), specification URI,
and registration date.
Note (working-group): Whether low-risk profiles (e.g., new domain entity types) should follow a lighter-weight registration with designated expert review instead of full consensus is under evaluation.
This part defines a registry of recognized scope values for the
scope field in um:agentDelegation pointers (Base
§6.5), with a namespace convention and registration procedure.
Namespace convention. Scope values MUST follow a
dot-separated <domain>.<capability> naming (the
domain identifies the functional area; the capability the specific
authority). Examples: spatial.session,
social.messaging, commerce.transaction. Custom
scope values defined by profile documents SHOULD use a reverse-DNS
prefix to prevent collisions (e.g.,
com.example.custom-capability).
Core scope values. All evaluators recognizing
um:agentDelegation pointers MUST understand these:
spatial.session (participate in spatial computing sessions
on behalf of the subject); spatial.navigation (navigate
spatial environments); social.messaging (send and receive
messages); social.presence (represent the subject's
presence status); commerce.transaction (initiate
transactions, within any spending limits declared in the manifest);
identity.attestation (present the subject's identity claims
to verifiers — does not grant authority to create or
modify claims).
Evaluator behavior for unrecognized scopes. An evaluator encountering unrecognized scope values MUST: (1) record them in the receipt; (2) restrict the delegate to only the recognized scopes (the delegate MUST NOT exercise capabilities for unrecognized scopes); (3) if the pointer contains only unrecognized scopes, SHOULD treat the delegation as having no effective scope and record this.
Registration procedure. New scope values are
registered through the profile registration mechanism (O6); a registration MUST
include the scope string, a description, the domain it governs, and any
constraints (e.g., "requires requiredTrustTier >=
1").
(Non-normative: Mastercard's Verifiable Intent pattern — a three-layer SD-JWT structure for bounded-scope agent delegation — is compatible, each layer mapping to a scope constraint. Working-group note: whether scope values should use URI-based naming for stronger uniqueness is under evaluation.)
trustWeight PREVIEWA recurring failure mode in service directories is treating a
self-declared service category (for example "emergency-services" or
"verified-merchant") as if it were attested. v0.4 separates the
claim of a category from its attestation by splitting
the single self-declared category field into four distinct
category-trust claim objects and by replacing the v0.1/v0.3
interpretedAs: "hint-only" enum with a typed
trustWeight field an evaluator can act on uniformly.
The trustWeight field. Any claim or
category-trust object MAY carry a trustWeight field
replacing the older interpretedAs: "hint-only" convention.
trustWeight is one of: "hint" (self-asserted,
unattested; evaluators MUST NOT grant trust-transitive or high-impact
authority on a hint-weighted value alone — the typed
successor to interpretedAs: "hint-only");
"attested" (backed by a Verifiable Credential or
attestation from a named issuer; evaluators verify per the claim-proof
process — EXT-T1
§T1.5 — before relying on it); "authoritative" (issued
by an identity service provider or registry the evaluator treats as
authoritative for the category by local policy). When
trustWeight is absent, evaluators MUST default to
"hint". Evaluators encountering the deprecated
interpretedAs member (from v0.1/v0.3) MUST ignore it; in
its absence trustWeight defaults to "hint",
preserving the prior interpretedAs: "hint-only" semantics.
The interpretedAs member is removed from the v0.4
vocabulary.
Category trust split. The single self-declared
category is replaced by four distinct category-trust objects
(claim-level objects carried in the claims array,
distinguished by their @type; not top-level
um:Facet objects), each carrying the common claim members
of Base
§1.4.3 plus trustWeight: operatorIdentity
(the operating entity's identity, signed by an identity service
provider; RECOMMENDED for any non-trivial service);
serviceCategoryClaim (the self-declared category; always
trustWeight: "hint" unless paired with a
categoryAttestation); categoryAttestation (a
Verifiable Credential attesting the category from a recognized
authority; REQUIRED for high-impact categories — defined at the profile
level, e.g. emergency, medical, financial, child-directed);
urgencyClaim (any urgency/priority assertion, carried as a
separate signed claim so urgency cannot be smuggled in via the category
field). Normative rules: an evaluator MUST NOT act on a
serviceCategoryClaim for a high-impact category without a
verified categoryAttestation; MUST verify
categoryAttestation credentials for revocation per O2; and MUST treat
operatorIdentity and serviceCategoryClaim as
independent. The high-impact category list is profile-level, not fixed
by this specification, consistent with eIDAS 2.0 [eIDAS2] assurance-level practice.
Preview: The trustWeight field and the
four-way category-trust split are built on the editors' default (adopt
trustWeight in v0.4). trustWeight is a small
but forward-compatibility-critical wire-shape change; doing it before
the wire is fielded avoids a v0.5 break. Input is requested on the
high-impact category list and on whether trustWeight should
be a closed enum or an extensible vocabulary.
The Base names three structural-state extensions as reserved members (Base §1.4.4, §1.4.6, §1.4.7); this part specifies them.
Spatial-computing sensors expose data at very different sensitivities
depending on processing. A single boolean "eye-tracking allowed" consent
cannot distinguish "raw gaze vector stream" from "region-of-interest hit
only." v0.4 extends the consents vocabulary (Base
§1.4.4) with derived-variant consent keys: each
sensor class is qualified by a derivation tier so holders consent to the
minimum-sensitivity variant a use case needs. Non-breaking: the v0.1
boolean keys remain valid and are interpreted as the most-permissive
variant only when a deployment explicitly opts in; absent an explicit
grant for a derived variant, evaluators MUST fail closed.
A derived-variant consent key uses dot-separated
sensor.<class>.<signal>.<derivation>
naming, aligned with the Khronos OpenXR sensor classes [OPENXR]. Eight sensor classes (eye, hand, face,
body, depth, audio, rgb-camera, environment) are each qualified by a
derivation tier from raw (least processed, most sensitive)
through progressively more-derived variants (e.g.
roi-derived, event-derived,
presence-derived). Examples:
sensor.eye.gaze.raw (raw gaze vector stream);
sensor.eye.gaze.roi-derived (region-of-interest hit-test
results only); sensor.hand.pose.raw (full hand skeleton);
sensor.hand.pose.gesture-derived (recognized discrete
gestures only). Each derived-variant consent entry MUST carry the
purpose field of Base
§1.4.4, binding the grant to a stated purpose so a grant for one
purpose cannot be silently reused for another (consent-creep prevention,
per GDPR Article 5(1)(b) and ISO/IEC 27560:2023). The
purpose value SHOULD be drawn from the W3C Data Privacy
Vocabulary where an applicable term exists. An evaluator MUST match the
most specific derived-variant key granted: a grant for
sensor.eye.gaze.roi-derived MUST NOT be read as granting
sensor.eye.gaze.raw. A grant for a less-derived (more
sensitive) variant MAY be treated by policy as also authorizing strictly
more-derived variants of the same signal, but a deployment doing so MUST
document the implication in its conformance claim.
(Worked example: derived-variant sensor consent with purpose binding — see Cookbook.)
Preview: Built on the editors' default (add in v0.4;
small, non-breaking). Input is requested on the full derivation-tier
enumeration per sensor class and on whether the sensor key is best
carried as a dedicated sensorConsent field or folded into
scope.
devices
SchemaThe devices array (Base
§1.4.6) registers hardware endpoints (XR headsets, NFC readers,
smart displays, wearable sensors) associated with the subject. v0.3
reserved this member; v0.4 defines device entries as a
two-component split mirroring the layered
device-attestation models of FIDO, TPM 2.0, WebAuthn Level 3 [WEBAUTHN], Android Hardware Attestation, and
Apple DeviceCheck: a long-lived hardware provenance component and a
session-scoped capability component. Separating them lets a session-only
manifest advertise device capabilities without leaking a long-lived
hardware identifier. Each entry is a device object that MAY carry a
deviceAttestation, a deviceCapability, or
both; it MUST include a @type of "um:Device"
and an @id. The deviceAttestation and
deviceCapability sub-objects are device
components, not um:Facet objects.
deviceAttestation (long-lived,
manufacturer-signed). When present it MUST contain
deviceClass (a string, e.g. "xr-headset",
"nfc-reader", "wearable-sensor"),
modelHash (a hash identifying the model/firmware baseline,
suitable for matching against a manufacturer registry without revealing
a per-unit serial), and attestation (a Verifiable
Credential or platform attestation object signed by the manufacturer or
attestation authority — e.g. a WebAuthn/FIDO device attestation or a TPM
2.0 [TPM2] quote; evaluators MUST verify it
against a configurable manufacturer trust anchor before relying on the
device's hardware claims). It MAY carry manufacturer
(DID/URI) and attestedAt (RFC 3339). Because hardware
identifiers are long-lived and potentially correlatable, holders SHOULD
omit deviceAttestation from session-only or pseudonymous
manifests and carry only deviceCapability.
deviceCapability (session-scoped,
user-signed). Describes what the device can do for the current
session, signed by the subject (or a session-scoped key), not the
manufacturer. When present it MAY contain sensors
(sensor-class identifiers, e.g. "eye-tracking",
"hand-tracking", "depth",
"rgb-camera", using OpenXR sensor-class naming),
openxrExtensions (OpenXR extension identifiers the
device/runtime supports), positioningTier (e.g.
"3dof", "6dof", "world-scale"),
processingConstraints (compute/thermal/power limits an
evaluator should respect), privacyModes (e.g.
"on-device-only", "roi-derived-only"), and
sessionSigningKey (a session-scoped ephemeral public key
used to sign per-session device assertions; MUST NOT be a long-lived
hardware identifier; generated per session to avoid cross-session
linkage). Evaluators MUST NOT treat deviceCapability claims
as hardware-attested unless a corresponding verified
deviceAttestation is present on the same entry; absent such
attestation, deviceCapability is a self-declared,
session-scoped assertion (analogous to a hint-weight claim — O8).
The devices array is part of the signed payload: holders
include it when signing, and evaluators MUST include it when recomputing
the signing input and MUST NOT discard it before verification or during
Arrive-stage unknown-field handling (it is a named structural member).
Evaluators that do not implement the device components MUST preserve the
array and record entries as present-but-unprocessed.
(Worked example: device entry with both components — see Cookbook.)
Preview: The two-component split is built on the editors' default (define in v0.4), because the wire shape is not yet fielded and this is the most consequential wire-shape decision in this version. Attestation transparency logs for device attestations are out of scope for v0.4 (flagged for v0.5). Input is requested on the sensor-class and OpenXR-extension vocabularies and on session-key generation requirements.
actorState MemberThe actorState member (Base
§1.4.7) is an OPTIONAL top-level object declaring who is operating
the session the manifest is presented in: the human principal, a
delegated agent, or a hybrid. It bridges the
um:agentDelegation pointer (Base
§6.5) — which declares that delegation exists — to the
session-state semantics of who is currently acting. RECOMMENDED
whenever an um:agentDelegation pointer is present.
When present, actorState MUST contain
principal (the DID of the human or legal entity the
manifest represents; MUST match the manifest subject; an
evaluator finding actorState.principal not equal to
subject MUST record this as a verification failure and MUST
NOT rely on the manifest for delegated-authority decisions). When
present, it MAY contain an executor object describing who
is operating on the principal's behalf: type (one of
"human", "agent", "hybrid"; MUST
be present when executor is present);
delegateId (the DID of the operating agent; REQUIRED when
type is "agent" or "hybrid");
delegationRef (a reference to the
um:agentDelegation pointer by @id that
authorizes this executor; when present, evaluators MUST confirm the
referenced pointer exists, is unexpired, and names
delegateId as its delegate); lastVerifiedAt
(RFC 3339 of the last interactive verification of the principal;
meaningful only when type is "human" or
"hybrid"; relates to the liveness model in EXT-T1
§T1.3). When executor is absent, evaluators MUST treat
the session as principal-operated (type: "human" with no
delegate). actorState is additive and non-breaking; v0.3
manifests omit it, and evaluators that do not implement it record it as
present-but-unprocessed.
(Worked example: actorState with an agent executor — see Cookbook.)
Preview: Built on the editors' default (add as
OPTIONAL, RECOMMENDED with um:agentDelegation). It is a
wire-shape addition. Input is requested on whether
actorState should become REQUIRED when any delegation
pointer is present.
This consolidates the cryptographic requirements scattered across the signature profile (Base §1.6), encrypted facets (Base §2.4), the tiered trust model (Base §6.4.2), the ZKP profiles (EXT-T2 §T2.1), the ceremony model (EXT-T3), credential binding (EXT-T1), and post-quantum signatures (EXT-T2 §T2.3) into a single reference. This is a summary; the normative requirement for each algorithm lives in its referenced section, so this table can be updated as profiles are added without editing those sections.
| Requirement level | Algorithms / cryptosuites | Reference |
|---|---|---|
| Mandatory-to-implement | Ed25519 over JCS-RFC8785 (Signature Profile A); SD-JWT Key Binding (KB-JWT); JWK Thumbprint; ECDH-ES+A256KW / A256GCM for encrypted facets | Base §1.6, EXT-T1 §T1.1, Base §2.4 |
| Recommended | BBS+ signatures and BBS+ derived proofs (BLS12-381); WebAuthn Level 3 device/liveness attestation | EXT-T2 §T2.1, EXT-T1 §T1.3 |
| Optional (Tier 2 profiles) † | Groth16 (HD-derivation proofs); BBS+ linked-secret equality proofs | EXT-T2 §T2.1 |
| Future | FROST threshold Schnorr/Ed25519 [RFC9591]; threshold BBS+; ML-DSA / SLH-DSA / FN-DSA post-quantum signatures | EXT-T3, EXT-T2 §T2.3 |
† Items marked "Optional (Tier 2 profiles)" are optional at the specification level but become mandatory within the named optional profile: Groth16 is REQUIRED for an implementation that supports Profile 2B. The mandatory-to-implement row is likewise scoped to the module that uses each algorithm: Ed25519 over JCS-RFC8785 is unconditional for every implementation; the JWE pair is mandatory for evaluators claiming encrypted-facet support; SD-JWT Key Binding and JWK Thumbprint are mandatory for implementations claiming credential-binding support.
Preview: Built on the editors' default (add as a reference summary). Input is requested on whether any "recommended" item (notably BBS+ for privacy-preserving Tier 2) should be elevated to mandatory-to-implement for v0.4.
This consolidates Base §4.7 with the modules this companion introduces. An implementation that does not implement an optional module still conforms, provided it observes the mandatory baseline behavior for that module.
| Feature | Conformance | Mandatory baseline when not implemented |
|---|---|---|
| Encrypted-facet decryption (Base §2.3) | OPTIONAL | Sealed-entry handling REQUIRED: record present-but-sealed; never infer content. |
| Revocation-aware verification (O2) | RECOMMENDED | Record revocationStatus: "unchecked"; do not grant
revocation-gated trust. |
| Credential binding (EXT-T1) | OPTIONAL (REQUIRED for Tier 1+) | Record holderBindingStatus: "absent"; cap relied-upon
claims at Tier 0. |
| CBOR-LD encoding (O1.4) | OPTIONAL | Support JSON-LD reference encoding; reject unsupported encodings. |
| Transparency anchoring (O3.4) | OPTIONAL | Verify the manifest signature and proofs directly; do not require a transparency log. |
| Tier-2 cryptographic binding (EXT-T2) | OPTIONAL | Record "trustTierUnsupported" for Tier-2-required
items; do not downgrade. |
| Tier-3 ceremony (EXT-T3) | OPTIONAL | Record "trustTierUnsupported" for Tier-3-required
items; do not downgrade. |
| Bilateral session model (O4) | OPTIONAL | Manifest-level bilateral exchange (Base §6.4.6) still applies. |
| Federation (O5) | OPTIONAL | Single-endpoint statusRef resolution (O2) applies. |
This appendix is informative. It snapshots the manifest classes (Base §1.0.1) currently surfaced by integration profiles, to illustrate the polymorphic-envelope model. It does not bind conformance; the authoritative, versioned registry is maintained as a standalone document under the profile registration mechanism (O6). Discriminating members are the members whose presence identifies the class.
| Manifest class | Discriminating members | Purpose |
|---|---|---|
| Identity capsule | claims[] with identity claim types;
holderBinding |
Portable identity and credential presentation. |
| Consent record | consents[] with um:Consent entries |
Records permission grants governing facet use. |
| Device-capability descriptor | devices[] with deviceCapability |
Advertises session-scoped device capabilities. |
| Device-attestation record | devices[] with deviceAttestation |
Conveys manufacturer-signed hardware provenance. |
| Receipt | @type includes um:Receipt;
seq/prevHash |
Signed, chainable evaluation/audit record. |
| Cross-DID binding | claims[] with
identity.crossDidBinding |
Asserts common control of multiple DIDs. |
| Agent-delegation capsule | pointers[] with um:agentDelegation;
actorState |
Declares delegated session authority and the operating actor. |
| Encrypted-facet carrier | facets[] with encryptionProfile |
Carries sealed, recipient-scoped payloads. |
| Category/service descriptor | claims[] with operatorIdentity /
categoryAttestation types |
Describes a service with attested category trust. |
| Bilateral-session record | @type um:BilateralSession;
exchangeId |
Correlates a two-party manifest exchange. |
The snapshot is illustrative and non-exhaustive; integration profiles
(e.g., the RP1 integration profile) surface additional classes. A
manifest may belong to more than one class at once; the normative rule
is in Base
§1.0.1. The bilateral-session-record row anticipates a manifest that
records a session: the session object of O4.1 is a protocol-layer object, not
itself a manifest, so a session-record manifest would carry the common
envelope members with @type including both
um:Manifest and um:BilateralSession; its class
profile is a working-group deliverable.
Cited in this profile (full descriptors in the published artifact): [DID-CORE], [INFRA], [JSON-LD], [CBOR-LD], [RFC8949] (CBOR), [RFC3339], [RFC9162] (Certificate Transparency 2.0), [MULTIFORMATS], [VC-STATUS] (Bitstring Status List), [UM-RFC], [eIDAS2], [OPENXR], [WEBAUTHN], [TPM2], [RFC9591] (FROST).
Companion to the Base specification. For worked examples, see the Cookbook.