Preview / Working Draft — v0.4 Conformance-Tier Stack. [PREVIEW] sections are under active development and subject to change.

Universal Manifest v0.4 — EXT-OPT

Optional-Feature Profiles

This document:
/spec/v0.4/ext-opt/
Document set:
Universal Manifest v0.4 (Conformance-Tier Stack)
Latest stable version:
https://universalmanifest.net/spec/v0.3/
History:
https://universalmanifest.net/spec/ (version index and changelog)
Editors:
Universal Manifest Working Group

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.

EXT-OPT: Optional-Feature Profiles

Companion to: Base specification (Tier-0 / Tier-1 Core). Registry categories: spans domain, signature, and others (per feature).

Contents


O1. Abstract Data Model & Format Independence

The 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.

O1.1. Abstract Data Model

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):

  • type (set of strings, REQUIRED) — MUST include um:Manifest. Expressed as @type in JSON-LD.
  • id (string, REQUIRED) — globally unique opaque identifier. Expressed as @id.
  • contextReference (list, REQUIRED) — reference to the term definitions fixing property meaning. Expressed as @context in JSON-LD; carried as a compression context reference in CBOR-LD.
  • manifestVersion (string, REQUIRED); subject (string, REQUIRED); issuedAt, expiresAt (datetime, REQUIRED).
  • facets (list, OPTIONAL); claims, consents, pointers, devices (lists, OPTIONAL); requiredTrustTier (integer, OPTIONAL).
  • signature (map, REQUIRED) — integrity proof over the payload.
  • presentationProof (map, OPTIONAL); livenessAttestation (map, OPTIONAL) — credential-binding members (EXT-T1).
  • actorState (map, OPTIONAL, PREVIEW); postQuantumSignature (map, OPTIONAL, PREVIEW — EXT-T2).

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.

O1.2. Production Rules

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.

O1.3. JSON-LD Production Rule (Reference Encoding)

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).

O1.4. CBOR-LD Production Rule (Compact Encoding)

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:

  1. Production (encode). Begin with the JSON-LD production; using the context identified by contextReference, map each defined term to its integer token, then emit as CBOR. The contextReference is carried as a context identifier (not inlined term strings).
  2. Consumption (decode). Read the context identifier, load the corresponding context, reverse the integer-to-term mapping, and reconstruct the JSON-LD document; interpreting it under O1.3 yields the abstract manifest.

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.

O1.5. Signing and Production

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.)

O1.6. Conformance to the Abstract Data Model

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.

O1.7. Context Integrity (production detail)

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.)


O2. statusRef Resolution Schema

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.

O2.1. Resolution Procedure

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.

O2.2. Response Schema

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).

O2.3. Status Semantics

  • "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.

O2.4. Error Handling

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).

O2.5. Status Endpoint Conformance

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.)


O3. Receipt as a First-Class Manifest Class PREVIEW

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.

O3.1. Chain Integrity

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.

O3.2. Typed Event Vocabulary

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.

O3.3. Structured Reason Registry

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).

O3.4. Transparency-Log Anchoring (optional)

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.


O4. Bilateral Session Model PREVIEW

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.

O4.1. Session Object

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.

O4.2. Session Lifecycle

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.

O4.3. Paired Receipt Correlation

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.

O4.4. Transport Independence

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.


O5. Federation PREVIEW

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.


O6. Profile Registration Mechanism PREVIEW

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.


O7. Agent-Delegation Scope Registry PREVIEW

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.)


O8. Category Trust and trustWeight PREVIEW

A 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.


O9. Extended Structural Schemas PREVIEW

The Base names three structural-state extensions as reserved members (Base §1.4.4, §1.4.6, §1.4.7); this part specifies them.

O9.2. Two-Component devices Schema

The 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.

O9.3. actorState Member

The 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.


O10. Cryptographic Requirements Summary PREVIEW

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.


O11. Optional-Feature Matrix (consolidated)

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.

Appendix OA. Manifest Class Registry Snapshot PREVIEW

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.

References

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.