The Universal Object & Resource Attestation (UORA) Protocol defines a complete, vendor-neutral framework for decentralized identity, state verification, and lifecycle tracking of physical assets across untrusted parties. Unlike data-format specifications that define only syntax, UORA defines a protocol: a set of rules for how attestations are issued, discovered, validated, and reconciled — with sufficient detail that a conformant implementation can be built from this document alone.

This specification addresses the four pillars of decentralized supply chain trust:

  1. Governance & Authorization: A verifiable chain of authority ensuring that only certified entities may issue specific attestation types for specific product categories, through decoupled CertificationCredentials with a BitstringStatusList revocation mechanism.
  2. Standardized Discovery: The UORA-Query-API, a uniform HTTP protocol mandating a single standardized endpoint structure and response format, with full normative detail sufficient for independent Resolver implementation.
  3. Deterministic State Reconciliation: A cryptographically linked antecedent chain supporting both linear sequences and DAGs, with a conflict resolution cascade that uses governance authority as the primary arbiter — eliminating timestamp-race vulnerabilities — plus normative DAG depth and cycle-detection rules.
  4. Conformance & Testability: 22 fully specified test vectors defining three conformance levels with independently verifiable, machine-executable criteria.

This is a Community Group Draft. It has been released for review and comment. Implementors are advised against deploying this material in production systems until it reaches Candidate Recommendation status. Please report issues at https://github.com/uora-wg/core/issues.

Introduction

Global supply chains operate across jurisdictional boundaries, regulatory regimes, and competing commercial interests. Traditional traceability systems rely on centralized databases, proprietary APIs, and bilateral agreements — each a single point of failure, a trust bottleneck, and an interoperability barrier. The UORA Protocol replaces these fragile architectures with a decentralized, cryptographically verifiable framework where trust is derived from governance authority and mathematics, not from any single participant or shared clock.

The protocol is organized into four architectural layers:

Relationship to Companion Specifications: This Core Protocol provides all normative rules required to build a conformant Issuer, Resolver, and Verifier. The companion UORA Secure Physical Binding specification is normatively required only for physical binding verification (BAL declarations, PUF Interface Descriptors, Proximity Verifier Service). It is not required for software-only implementations.

Terminology

The key words MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL in this document are to be interpreted as described in [[RFC2119]].

Issuer
Entity that creates and cryptographically signs attestations. MUST possess a valid CertificationCredential for the specific attestation type and product category being asserted.
Holder
Entity possessing the physical object and its attestation chain. MAY present attestations to Verifiers for inspection. Does not sign attestations.
Verifier
Entity that validates attestations using the governance rules, antecedent chain integrity, linear custody chain enforcement, and conflict resolution cascade defined herein. The Verifier MAY be untrusted; the protocol is designed so that verifiers learn only public information.
Trust Anchor
Governance body that issues CertificationCredentials to legitimate Issuers according to a published Trust Framework. The Trust Anchor is the root of authority for a specific domain or industry.
Resolver
Service implementing the UORA-Query-API for standardized attestation discovery, history retrieval, and validation. A Resolver MAY be operated by any party.
Trust Framework
A published document defining governance rules for a specific domain: recognized Trust Anchors, required CertificationCredential schema, authority precedence table for conflict resolution cascade, and audit requirements.
Antecedent
The cryptographically referenced predecessor attestation(s) upon which a given attestation builds. SHALL be null for origin events, a single attestation ID for linear chains, or an ordered array for DAG-based transformations.
Antecedent Chain
The complete, cryptographically linked sequence of attestations from an object's origin to its current state, formed by traversing antecedent references.
Conflict Resolution Cascade
The deterministic, three-tier algorithm (authority → timestamp → attestation ID) that resolves competing attestations claiming the same antecedent without requiring external consensus. Authority is the primary tier; timestamp is secondary.
Linear Custody Chain Enforcement
The rule requiring Transfer and Disposition attestations to reference the most recent valid event, preventing custody gaps and ensuring a complete audit trail.
Authority Precedence
A numeric rank assigned to each recognized Issuer by the Trust Anchor in the applicable Trust Framework. Higher integers denote higher authority. Authority precedence is the primary discriminator in the Conflict Resolution Cascade.
DAG Depth
The maximum number of antecedent hops a Resolver MAY traverse when validating a Directed Acyclic Graph attestation chain. Defined normatively as 64 hops.
CertificationCredential
A W3C Verifiable Credential issued by a Trust Anchor to an Issuer, authorizing that Issuer to create specific attestation types for specific product categories within a defined validity window. Uses BitstringStatusList for revocation.
UORA-Query-API
The standardized HTTP API that every UORA-compliant Resolver MUST implement for attestation discovery, capture, validation, and chain inspection.

Architecture

Protocol Layers

The UORA Protocol Architecture — Four-Layer Trust Stack
4 Domain Profiles

Extends UORAAttestation subtypes with industry-specific claims (Pharma, CriticalMinerals, FoodBeverage, Customs, Aerospace). All profiles inherit validation rules from Layers 2–3. Profiles MUST NOT override governance, chaining, or conflict rules.

Industry-specific extensions require no core protocol changes.
extends and inherits from
3 Governance & Authorization

CertificationCredentials issued by Trust Anchors to Issuers, with BitstringStatusList revocation. Trust Frameworks define authority precedence tables. Every attestation MUST reference a valid, unexpired, non-revoked CertificationCredential.

Decoupled from core schemas — trust models evolve independently.
validates issuer authority via
2 Core Attestation Schemas

Four concrete attestation types: Origin, Transfer, Transformation, Disposition. Antecedent chaining (linear and DAG, with depth limits and cycle detection). Conflict resolution cascade (authority → timestamp → ID). Linear custody chain enforcement.

Complete, automatable supply chain event modeling.
resolves and discovers via
1 Universal Object Addressing & Discovery

DID-based object identification (serial, batch, SKU granularity). Standardized UORA-Query-API with six endpoints fully specified herein. Physical binding metadata (companion spec required only for binding verification).

Every object has a single, uniform discovery interface.

Protocol Roles

Trust Anchor

Publishes Trust Framework; issues and revokes CertificationCredentials; configures authority precedence table.

✍️
Issuer

Creates and signs attestations; references valid CertificationCredential in every attestation.

📦
Holder

Possesses the physical object; presents attestation chains to Verifiers.

🔍
Verifier

Validates structure, governance, chain integrity, and conflict resolution.

🖥️
Resolver

Implements UORA-Query-API; stores or proxies attestations; executes the validation pipeline.

Attestation Type Hierarchy

UORA Attestation Type Hierarchy — UML Class Diagram
«abstract» UORAAttestation
  • id: URI (UUID URN)
  • type: [VerifiableCredential, UORAAttestation, ...]
  • validFrom: DateTime (ISO 8601)
  • eventType: Origin | Transfer | Transformation | Disposition
  • antecedent: URI | Array<URI> | null
  • authorizedBy: Object
  • evidence: Array (min 1)
  • proof: DataIntegrityProof

UORAOriginAttestation
  • originType: String
  • originLocation: URI
  • originDate: DateTime
  • productionBatch?: String
  • inputMaterials?: Array<URI>
UORATransferAttestation
  • transferType: custody | ownership | location
  • fromParty: URI
  • toParty: URI
  • fromLocation?: URI
  • toLocation?: URI
UORATransformationAttestation
  • transformationType: String
  • inputObjects: Array<URI>
  • outputObjects: Array<URI>
  • inputQuantities?: Array
  • outputQuantities?: Array
UORADispositionAttestation
  • dispositionType: String
  • dispositionLocation?: URI
  • environmentalCertification?: URI

Universal Object Addressing & Discovery

DID Method for Physical Objects

Every physical object tracked by UORA SHALL be assigned a Decentralized Identifier (DID) resolvable to a DID Document. The DID Document provides cryptographic verification material, the Resolver service endpoint, and optional physical binding metadata.

DID Pattern:

did:web:{domain}:object:{granularity}:{identifier}
GranularityExample DIDUse CaseAntecedent Behavior
serialdid:web:maker.example.com:object:serial:SN-001Individual item trackingSingle linear chain
lotdid:web:maker.example.com:object:lot:L-2026-04Batch-level traceabilityMay reference DAG antecedents
skudid:web:maker.example.com:object:sku:GTIN-123456Product class definitionLifecycle events at higher granularity

DID Document Structure

A UORA-compliant DID Document SHALL include verification material and a service endpoint declaring the UORA-Query-API base URL.

{
  "@context": ["https://www.w3.org/ns/did/v1"],
  "id": "did:web:maker.example.com:object:serial:SN-001",
  "verificationMethod": [
    {
      "id": "#key-1",
      "type": "Ed25519VerificationKey2020",
      "controller": "did:web:maker.example.com:object:serial:SN-001",
      "publicKeyMultibase": "zH3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
    }
  ],
  "assertionMethod": ["#key-1"],
  "service": [
    {
      "id": "#attestation-history",
      "type": "UORAAttestationService",
      "serviceEndpoint": "https://maker.example.com/uora/v1"
    }
  ]
}
            

UORA-Query-API Protocol

Every UORA-compliant Resolver SHALL implement this standardized query interface at the serviceEndpoint declared in the object's DID Document.

Endpoint Reference

MethodPathPurposeIdempotent
GET{base}/historyRetrieve attestation history for an objectYes
POST{base}/attestationsSubmit and validate a new attestationNo
POST{base}/validateValidate an attestation without storingYes
GET{base}/chainRetrieve human-readable custody chain timelineYes
GET{base}/healthResolver health checkYes
GET{base}/statsResolver store statisticsYes

Request Parameters — GET /history

ParameterRequiredTypeDescription
didMUSTURIDID of the physical object
eventTypeOPTIONALStringFilter: Origin, Transfer, Transformation, Disposition
fromOPTIONALISO 8601Return attestations where validFrom >= from
toOPTIONALISO 8601Return attestations where validFrom <= to
limitOPTIONALIntegerMaximum results (default: 100, max: 1000)
includeSupersededOPTIONALBooleanIf true, include attestations with status superseded (default: false)

Response: 200 OK for GET /history

{
  "did": "did:web:maker.example.com:object:serial:SN-001",
  "attestations": [
    {
      "id": "urn:uuid:origin-attestation-id",
      "type": ["VerifiableCredential", "UORAAttestation", "UORAOriginAttestation"],
      "validFrom": "2026-01-15T08:00:00Z",
      "issuer": "did:web:maker.example.com",
      "eventType": "Origin",
      "antecedent": null,
      "status": "valid",
      "chainIntegrity": "intact",
      "supersededBy": null,
      "proof": { "type": "Ed25519Signature2020" },
      "credential": { /* full verifiable credential */ }
    }
  ],
  "total": 1
}
                

Response: 201 Created for POST /attestations

{
  "status": "accepted",
  "attestationId": "urn:uuid:550e8400-e29b-41d4-a716-446655440000",
  "chainIntegrity": "intact",
  "eventType": "Transfer",
  "antecedent": ["urn:uuid:origin-attestation-id"]
}
                

Response: 200 OK for POST /validate

{
  "status": "valid",
  "error": null,
  "chainIntegrity": "intact",
  "details": {
    "attestationId": "urn:uuid:550e8400-e29b-41d4-a716-446655440000",
    "issuer": "did:web:shipper.example.com",
    "eventType": "Transfer",
    "antecedent": ["urn:uuid:origin-attestation-id"],
    "proofType": "Ed25519Signature2020",
    "phasesExecuted": [1, 2, 3, 4, 5, 6, 7]
  }
}
                

Response: 200 OK for GET /chain

{
  "did": "did:web:maker.example.com:object:serial:SN-001",
  "chainLength": 3,
  "dagDepth": 1,
  "isComplete": true,
  "chain": [
    {
      "position": 1,
      "eventType": "Origin",
      "attestationId": "urn:uuid:origin-attestation-id",
      "timestamp": "2026-01-15T08:00:00Z",
      "issuer": "did:web:maker.example.com",
      "description": "Object created at https://id.gs1.org/414/9521321000010"
    }
  ]
}
                

Response: 200 OK for GET /health

{
  "status": "ok",
  "version": "1.0",
  "conformanceLevel": "UORA-Full-Compliant",
  "timestamp": "2026-05-01T00:00:00Z"
}
                

Error Responses (Normative)

HTTP StatusConditionBody field error
400Missing required did parameter or malformed JSON bodybad_request
404DID not found or no attestation history availablenot_found
409Duplicate attestation ID detected (Phase 1)rejected_duplicate_id
422Attestation rejected by any validation pipeline phasePhase-specific rejection status
500Internal Resolver errorinternal_error

All error responses MUST include a JSON body with fields error (string), message (human-readable string), and phase (integer 1–7 identifying the failing pipeline phase, or null for non-pipeline errors).

Secure Physical Binding Reference

A UORA digital identity MUST be bound to its physical counterpart through at least one tamper-evident mechanism. The normative specification is the companion UORA Secure Physical Binding protocol. This companion specification is required only for physical binding verification; it is not required to implement a conformant Resolver or Verifier operating on software-presented credentials.

Binding MechanismSecurity LevelTypical Application
Cryptographic NFC TagHighIndividual high-value items with challenge-response
Secure QR with Digital SignatureMediumBatch-level tracking with visual inspection
IoT Hardware Security Module (HSM)HighContainers and equipment with continuous attestation
Physically Unclonable Function (PUF)Very HighCritical components and luxury goods

Governance & Authorization

Certification of Authority

An attestation SHALL NOT be considered valid unless the Issuer possesses a valid, non-revoked CertificationCredential (UORACertificationCredential) for the specific attestation type and product category.

CertificationCredential Schema

{
  "@context": [
    "https://www.w3.org/ns/credentials/v2",
    "https://w3id.org/uora/contexts/core.jsonld"
  ],
  "id": "urn:uuid:cert-credential-id",
  "type": ["VerifiableCredential", "UORACertificationCredential"],
  "issuer": {
    "id": "did:web:trust-anchor.example.com",
    "name": "Pharmaceutical Trust Anchor Consortium"
  },
  "validFrom": "2026-01-01T00:00:00Z",
  "validUntil": "2027-01-01T00:00:00Z",
  "credentialStatus": {
    "id": "https://trust-anchor.example.com/status/1#42",
    "type": "BitstringStatusListEntry",
    "statusPurpose": "revocation",
    "statusListIndex": "42",
    "statusListCredential": "https://trust-anchor.example.com/status/1"
  },
  "credentialSubject": {
    "id": "did:web:certified-issuer.example.com",
    "authorizedAttestations": [
      "UORAOriginAttestation",
      "UORATransferAttestation",
      "UORATransformationAttestation"
    ],
    "authorizedCategories": ["pharmaceuticals", "medical-devices"],
    "authorizedRegions": ["global"],
    "authorityPrecedence": 50,
    "trustFramework": "https://w3id.org/verifiable-supply-chain/trust-frameworks/pharma-v1"
  }
}
                
The authorityPrecedence field is the canonical source of an Issuer's precedence rank. It MUST match the value in the Trust Framework's authority precedence table. In case of conflict, the CertificationCredential value is authoritative.

authorizedBy Claim

Every UORAAttestation MUST include an authorizedBy claim referencing a valid CertificationCredential.

{
  "credentialSubject": {
    "authorizedBy": {
      "certificationId": "urn:uuid:cert-credential-id",
      "trustFramework": "https://w3id.org/verifiable-supply-chain/trust-frameworks/pharma-v1",
      "verifiedAt": "2026-04-28T10:30:00Z"
    }
  }
}
                

Governance Validation Rules

A Verifier SHALL reject any attestation where:

ConditionRejection StatusRemediation
The authorizedBy claim is absentrejected_missing_authorizationIssuer MUST add the claim and reissue
The referenced certificationId cannot be resolvedrejected_unauthorized_issuerIssuer MUST obtain a valid CertificationCredential
The attestation's validFrom falls outside the certification's validity windowrejected_expired_certificationIssuer MUST renew certification before issuing
The CertificationCredential is revoked (per BitstringStatusList check)rejected_revoked_certificationIssuer MUST obtain a new CertificationCredential
The attestation type is not in authorizedAttestationsrejected_unauthorized_categoryIssuer MUST obtain certification for this type
The Issuer DID does not match credentialSubject.idrejected_unauthorized_issuerAttestation MUST be issued by the certified entity

CertificationCredential Revocation

Trust Anchors MUST implement credential revocation using the W3C Bitstring Status List specification [[BITSTRING-STATUS-LIST]]. Verifiers MUST check the revocation status of every CertificationCredential during Phase 5 validation. The revocation check is not optional and MUST NOT be cached for longer than 5 minutes.

/* Revocation check algorithm */
1. Resolve credentialStatus.statusListCredential → StatusListCredential VC
2. Verify the StatusListCredential's proof
3. Decode the compressed bitstring (GZIP + base64url)
4. Check bit at index credentialStatus.statusListIndex
5. If bit = 1: reject with rejected_revoked_certification
6. If bit = 0: credential is valid (proceed with other checks)
                

Core Attestation Schemas

Antecedent Chaining & Deterministic State Reconciliation

Every UORA attestation SHALL reference its immediate predecessor through an antecedent property, creating a cryptographically linked, verifiable history chain. Conflict resolution cascade is governed by authority precedence — not timestamps — as the primary discriminator.

Linear Chains

For sequential events, the antecedent is a single attestation ID:

{ "credentialSubject": { "antecedent": "urn:uuid:previous-attestation-id" } }

Implementations SHALL normalize single antecedent strings to arrays during processing. The first attestation in an object's lifecycle SHALL have "antecedent": null.

Directed Acyclic Graph (DAG) Support

For transformations and aggregations, antecedent SHALL accept an ordered array:

{
  "credentialSubject": {
    "antecedent": [
      "urn:uuid:component-a-final-state",
      "urn:uuid:component-b-final-state",
      "urn:uuid:component-c-final-state"
    ]
  }
}
                

DAG Traversal Limits (Normative):

LimitValueRationale
Maximum DAG depth64 hopsPrevents unbounded recursion in deeply nested assembly chains
Maximum antecedent array width256 entriesLimits fan-in for aggregation events
Cycle detectionREQUIREDResolvers MUST maintain a visited-ID set; reject cycles with rejected_cyclic_chain
Traversal timeout30 secondsReject with rejected_traversal_timeout if exceeded
Any attestation whose antecedent graph contains a cycle is definitionally invalid and MUST be rejected. Cyclic references are an indicator of data corruption or an active attack.

DAG Validation Rule: A Verifier SHALL recursively validate every referenced branch. The attestation is valid only if ALL antecedent branches resolve to valid, non-superseded terminal states within the depth and timeout limits.

Conflict Resolution Cascade

If a Verifier encounters two attestations claiming to succeed the same antecedent, the conflict SHALL be resolved using this deterministic, three-tier cascade.

Conflict Resolution Cascade — Authority Precedence is Primary
1Authority
Authority Precedence (Primary)

The attestation from the Issuer with the higher authorityPrecedence value prevails. Always resolvable without examining timestamps. Governance supersedes chronology.

2Timestamp
Timestamp Precedence (Secondary)

If Issuers have identical authority precedence, the attestation with the later validFrom timestamp prevails (1-second tolerance). Reached only when co-equal authorities record competing events.

3Hash
Hash Precedence (Tiebreaker)

If authority and timestamps are equal, the attestation with the lexicographically smaller id prevails. Deterministic, requires no external input.

Authority Precedence Table Example:

{
  "trustFramework": "https://w3id.org/verifiable-supply-chain/trust-frameworks/pharma-v1",
  "authorityPrecedenceTable": {
    "did:web:fda.example.gov":           100,
    "did:web:manufacturer.example.com":   50,
    "did:web:wholesaler.example.com":     30,
    "did:web:retailer.example.com":       10
  }
}
                

Preservation Requirement: The losing attestation SHALL be preserved with "status": "superseded" and "supersededBy" set to the winning attestation's ID. Superseded attestations SHALL NOT be used for state computation.

Linear Custody Chain Enforcement

For Transfer and Disposition attestations, the Verifier SHALL enforce linear custody chain enforcement. The antecedent MUST reference the most recent valid event.

AttestationAntecedentMost Recent ValidResult
Originnullvalid
Transfer A (maker → distributor)origin-idorigin-idvalid
Transfer B (distributor → retailer)transfer-a-idtransfer-a-idvalid
Transfer C — VIOLATIONorigin-idtransfer-b-idrejected_linear_chain_violation

Exemptions: Origin events (antecedent: null) and Transformation events (multi-antecedent DAG) are exempt.

UORAAttestation (Abstract Base Type)

All UORA attestations SHALL extend this abstract base type.

["VerifiableCredential", "UORAAttestation", ""]
PropertyRequiredTypeDescription
@contextMUSTArrayVC v2 context + UORA Core context URI
typeMUSTArrayFull type chain: VerifiableCredential, UORAAttestation, exactly one concrete subtype
idMUSTURIGlobally unique identifier: urn:uuid:{uuid-v4}
issuer.idMUSTURIDID of the certified Issuer
validFromMUSTDateTimeISO 8601 UTC timestamp of the attested event
credentialSubject.idMUSTURIDID of the physical object
credentialSubject.eventTypeMUSTStringOrigin, Transfer, Transformation, Disposition
credentialSubject.antecedentMUSTURI | Array | nullPredecessor attestation ID(s); null for origin events
credentialSubject.authorizedByMUSTObjectCertification reference
evidenceMUSTArrayAt least one evidence entry
proofMUSTObjectW3C Data Integrity Proof

UORAOriginAttestation

Documents the creation, manufacture, mining, or harvest of a physical object. Root attestation; antecedent MUST be null.

PropertyRequiredTypeDescription
originTypeMUSTStringmanufactured, mined, harvested, created
originLocationMUSTURIPhysical location of origin (GS1 GLN or equivalent)
originDateMUSTDateTimeTimestamp of creation event
productionBatchOPTIONALStringBatch or lot identifier
inputMaterialsOPTIONALArray<URI>DID references to source materials

UORATransferAttestation

Documents a change of custody, ownership, or physical location. Antecedent MUST reference the most recent valid event per linear custody chain enforcement.

PropertyRequiredTypeDescription
transferTypeMUSTStringcustody, ownership, location
fromPartyMUSTURIDID of transferring party
toPartyMUSTURIDID of receiving party
fromLocationOPTIONALURIOrigin location before transfer
toLocationOPTIONALURIDestination location after transfer

UORATransformationAttestation

Documents processing, assembly, or modification. Only type supporting multi-antecedent DAG chains. Exempt from linear custody chain enforcement.

PropertyRequiredTypeDescription
transformationTypeMUSTStringassembly, processing, modification, disassembly
inputObjectsMUSTArray<URI>DID references to consumed input objects
outputObjectsMUSTArray<URI>DID references to produced output objects
inputQuantitiesOPTIONALArrayQuantities of each input
outputQuantitiesOPTIONALArrayQuantities of each output
transformationLocationOPTIONALURIPhysical location of transformation
processCertificationOPTIONALURIReference to process certification

Antecedent rule: SHALL be an array with at least one entry, one per inputObject. Subject to DAG traversal limits.

UORADispositionAttestation

Documents end-of-life, recycling, or decommissioning. Terminal attestation; no attestation SHALL reference a Disposition as its antecedent.

PropertyRequiredTypeDescription
dispositionTypeMUSTStringrecycled, decommissioned, destroyed, lost
dispositionLocationOPTIONALURIPhysical location of disposition
environmentalCertificationOPTIONALURIReference to environmental compliance certification

Evidence & Data Economy

Required Evidence

{
  "evidence": [
    {
      "id": "urn:uuid:evidence-unique-id",
      "type": ["Evidence"],
      "name": "Human-readable evidence name",
      "description": "Description of the evidence"
    }
  ]
}
                

EPCIS Evidence Linking

{
  "evidence": [
    {
      "id": "urn:uuid:evidence-unique-id",
      "type": ["Evidence", "EPCISObjectEvent"],
      "name": "EPCIS Shipping Event",
      "description": "Original EPCIS ObjectEvent with bizStep=shipping",
      "epcisEventID": "ni:///sha-256;abc123def456?ver=CBV2.0",
      "epcisEventType": "ObjectEvent",
      "epcisBizStep": "shipping"
    }
  ]
}
                

Data Economy Guidelines (Informative)

Data SizeRecommendationRationale
< 1 KBEmbed directly in evidenceNegligible overhead; always available
1 KB – 1 MBReference via externalDataBalance availability with chain size
> 1 MBMUST reference via externalDataAvoid large payloads in attestation history
{
  "externalData": {
    "uri": "https://storage.example.com/report-001.pdf",
    "hash": "sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
    "size": 1048576,
    "accessPolicy": "holder-controlled",
    "encryptedFor": null
  }
}
                

The accessPolicy field MUST be one of: public, holder-controlled, or encrypted. Verifiers MUST respect access policies.

Proof Section

Every attestation MUST carry a W3C Data Integrity Proof.

{
  "proof": {
    "type": "Ed25519Signature2020",
    "created": "2026-04-28T10:30:00Z",
    "verificationMethod": "did:web:shipper.example.com#key-1",
    "proofPurpose": "assertionMethod",
    "proofValue": "z5LbLbR3qZ5Y6m8n9o0p1q2r3s4t5u6v7w8x9y0za1b2c3d4..."
  }
}
            
FieldRequiredDescription
typeMUSTEd25519Signature2020, BbsBlsSignature2020, or DataIntegrityProof
createdMUSTISO 8601 UTC timestamp of proof creation
verificationMethodMUSTDID URL of the signing key
proofPurposeMUSTMUST be assertionMethod
proofValueMUSTCryptographic proof value

BbsBlsSignature2020 [[BBS-2023]] proofs enable selective disclosure. Support for BbsBlsSignature2020 is REQUIRED for Full Compliance.

Validation Pipeline

The UORA Resolver implements a seven-phase validation pipeline. Each phase executes sequentially; a rejection in any phase terminates processing.

Seven-Phase Validation Pipeline
1
Structural Validation
All mandatory fields present; id is a valid UUID URN; id is not a duplicate.
rejected_missing_field | rejected_duplicate_id
2
Type Validation
type array contains VerifiableCredential, UORAAttestation, and exactly one concrete subtype.
rejected_invalid_type | rejected_invalid_event_type
3
Temporal Validation
validFrom is not more than 5 seconds in the future.
rejected_future_timestamp
4
Proof Validation
Proof section present; cryptographic signature verifies against the Issuer's DID Document.
rejected_invalid_proof
5
Governance Validation
authorizedBy claim present; CertificationCredential is valid, unexpired, non-revoked; attestation type is authorized.
rejected_missing_authorization | rejected_unauthorized_issuer | rejected_expired_certification | rejected_revoked_certification | rejected_unauthorized_category
6
Antecedent Chain Validation
Antecedent references resolve within DAG depth (64), width (256), cycle detection, and 30s timeout limits. Linear custody chain enforcement for Transfer/Disposition.
rejected_broken_chain | rejected_linear_chain_violation | rejected_cyclic_chain | rejected_traversal_timeout
7
Conflict Resolution
No competing attestation with higher authority precedence claims the same antecedent.
superseded (preserved for audit, not used for state)

Validation Status Codes

StatusPhaseDescription
validAll seven phases passed; attestation is authoritative for state computation
superseded7Structurally valid; lost conflict resolution cascade; preserved for audit, not used for state
rejected_missing_field1Required field absent
rejected_duplicate_id1Attestation ID already processed
rejected_invalid_type2Type declaration mismatch or missing concrete subtype
rejected_invalid_event_type2eventType does not match declared subtype
rejected_future_timestamp3validFrom more than 5 seconds in the future
rejected_invalid_proof4Proof missing, unrecognized type, or cryptographic verification failure
rejected_missing_authorization5No authorizedBy claim
rejected_unauthorized_issuer5Issuer lacks valid CertificationCredential or DID mismatch
rejected_expired_certification5CertificationCredential expired at attestation time
rejected_revoked_certification5CertificationCredential revoked per BitstringStatusList
rejected_unauthorized_category5Attestation type not in certification's authorized scope
rejected_broken_chain6Antecedent reference cannot be resolved or DAG branch invalid
rejected_linear_chain_violation6Transfer/Disposition does not reference the most recent valid event
rejected_cyclic_chain6Antecedent graph contains a cycle
rejected_traversal_timeout6DAG traversal exceeded 30-second time limit

Chain Integrity States

StateMeaningAction Required
intactAntecedent chain is complete and all referenced attestations are validNone — automated processing continues
brokenUnresolvable antecedent, DAG branch failure, cycle, or traversal timeoutManual investigation required
invalidAttestation failed structural or governance validation (Phases 1–5)Attestation must be reissued with corrections

Complete Example

A complete, well-formed UORATransferAttestation that passes all seven validation phases.

{
  "@context": [
    "https://www.w3.org/ns/credentials/v2",
    "https://w3id.org/uora/contexts/core.jsonld",
    "https://w3id.org/verifiable-supply-chain/contexts/shipping.jsonld"
  ],
  "id": "urn:uuid:550e8400-e29b-41d4-a716-446655440000",
  "type": [
    "VerifiableCredential",
    "UORAAttestation",
    "UORATransferAttestation",
    "VerifiableShippingEvent"
  ],
  "issuer": {
    "id": "did:web:shipper.example.com",
    "name": "Global Logistics Co."
  },
  "validFrom": "2026-04-28T10:30:00.000Z",
  "credentialSubject": {
    "id": "did:web:maker.example.com:object:serial:SN-001",
    "eventType": "Transfer",
    "transferType": "custody",
    "fromParty": "did:web:shipper.example.com",
    "toParty": "did:web:receiver.example.com",
    "fromLocation": "https://id.gs1.org/414/9521321000010",
    "toLocation": "https://id.gs1.org/414/9521321000096",
    "antecedent": "urn:uuid:previous-origin-attestation-id",
    "authorizedBy": {
      "certificationId": "urn:uuid:shipper-cert-credential",
      "trustFramework": "https://w3id.org/verifiable-supply-chain/trust-frameworks/logistics-v1",
      "verifiedAt": "2026-04-28T10:30:00Z"
    }
  },
  "evidence": [
    {
      "id": "urn:uuid:evidence-001",
      "type": ["Evidence", "EPCISObjectEvent"],
      "name": "Custody Transfer Handover",
      "description": "Digital handover confirmation at dock door R1",
      "epcisEventID": "ni:///sha-256;abc123def456?ver=CBV2.0",
      "epcisEventType": "ObjectEvent",
      "epcisBizStep": "shipping"
    }
  ],
  "proof": {
    "type": "Ed25519Signature2020",
    "created": "2026-04-28T10:30:00Z",
    "verificationMethod": "did:web:shipper.example.com#key-1",
    "proofPurpose": "assertionMethod",
    "proofValue": "z5LbLbR3qZ5Y6m8n9o0p1q2r3s4t5u6v7w8x9y0za1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"
  }
}
        

Conformance & Test Vectors

Compliance Levels

📋
UORA-Data-Compliant

Produces attestations conforming to the data model. Passes Phases 1–2. Ed25519Signature2020 required. 9 test vectors (Categories A + B).

🔗
UORA-Protocol-Compliant

Meets Data compliance + implements UORA-Query-API with all six endpoints. Passes Phases 1–5 including revocation checks. 16 test vectors (Categories A–E + J).

UORA-Full-Compliant

Meets Protocol compliance + all seven phases including DAG limits, cycle detection, conflict resolution cascade, and BBS+ selective disclosure. All 22 test vectors.

Conformance Test Suite — All 22 Test Vectors

The following test vectors are normative. Test vectors are also published at https://w3id.org/uora/conformance/v1.0/vectors.json.

Category A — Valid Attestations (4 vectors, all levels)

TC-A-001valid

Well-formed UORAOriginAttestation with Ed25519 proof and valid CertificationCredential. Expected: accepted

TC-A-002valid

Well-formed UORATransferAttestation referencing a valid origin. Expected: accepted

TC-A-003valid

Well-formed UORATransformationAttestation with two-element DAG antecedent. Expected: accepted

TC-A-004valid

Well-formed UORADispositionAttestation as terminal event. Expected: accepted

Category B — Invalid Attestations (5 vectors, all levels)

TC-B-001invalid

Missing issuer.id. Expected: rejectedrejected_missing_field

TC-B-002invalid

Duplicate UUID submission. Expected: rejectedrejected_duplicate_id, HTTP 409

TC-B-003invalid

Type array missing concrete subtype. Expected: rejectedrejected_invalid_type

TC-B-004invalid

validFrom 60 seconds in the future. Expected: rejectedrejected_future_timestamp

TC-B-005invalid

Origin attestation with non-null antecedent. Expected: rejectedrejected_broken_chain

Category C — Governance Validation (3 vectors, Protocol + Full)

TC-C-001governance

authorizedBy claim absent. Expected: rejectedrejected_missing_authorization

TC-C-002governance

CertificationCredential expired before attestation. Expected: rejectedrejected_expired_certification

TC-C-003governance

Attestation type not in authorized scope. Expected: rejectedrejected_unauthorized_category

Category D — Revocation (1 vector, Protocol + Full)

TC-D-001revocation

CertificationCredential revoked in BitstringStatusList. Expected: rejectedrejected_revoked_certification

Category E — Proof Validation (2 vectors, Protocol + Full)

TC-E-001proof

Entire proof section omitted. Expected: rejectedrejected_invalid_proof

TC-E-002proof

Incorrect proofValue — signature verification fails. Expected: rejectedrejected_invalid_proof

Category F — Conflict Resolution (3 vectors, Full only)

TC-F-001conflict

Higher authority precedence wins (100 vs 50). Expected: A valid, B superseded. Tier 1 resolves.

TC-F-002conflict

Equal authority; later timestamp wins. Expected: A valid, B superseded. Tier 2 resolves.

TC-F-003conflict

Equal authority and timestamp; smaller UUID wins. Expected: A valid, B superseded. Tier 3 resolves.

Category G — Chain Integrity (2 vectors, Full only)

TC-G-001chain

Antecedent references non-existent UUID. Expected: rejectedrejected_broken_chain

TC-G-002chain

DAG branch resolves to superseded attestation. Expected: rejectedrejected_broken_chain

Category H — Linear Chain Enforcement (2 vectors, Full only)

TC-H-001linear

Transfer skips over a more recent valid event. Expected: rejectedrejected_linear_chain_violation

TC-H-002linear

Transfer correctly references most recent valid event. Expected: accepted

Category I — DAG Limits & Cycles (1 vector, Full only)

TC-I-001dag

Antecedent graph contains cycle (A→B→C→A). Expected: rejectedrejected_cyclic_chain

Category J — EPCIS Evidence Linking (1 vector, Protocol + Full)

TC-J-001epcis

Transfer attestation with EPCIS ObjectEvent evidence. Expected: accepted

Category K — Selective Disclosure (1 vector, Full only)

TC-K-001bbs

BbsBlsSignature2020 derived presentation with omitted location fields. Expected: accepted

Relationship to Domain Profiles

Domain-specific profiles SHALL extend the appropriate UORA attestation subtype and add industry-specific claims. Profiles SHALL NOT modify or override governance validation rules, antecedent chaining, linear custody chain enforcement, DAG traversal limits, or conflict resolution cascade.

UORA AttestationExample Domain ProfilesEPCIS Mapping
UORAOriginAttestationVerifiableCommissioningEventObjectEvent (ADD, bizStep=commissioning)
UORATransferAttestationVerifiableShippingEvent, VerifiableReceivingEventObjectEvent (OBSERVE, bizStep=shipping/receiving)
UORATransformationAttestationVerifiableManufacturingEvent, VerifiableAssemblyEventTransformationEvent
UORADispositionAttestationVerifiableRecyclingEvent, VerifiableDestructionEventObjectEvent (DELETE)

Privacy Considerations (Normative)

This section is normative. UORA attestations are designed for supply chain transparency, but the long-lived nature of object identifiers and immutable event histories creates significant privacy risks that implementations MUST address.

Selective Disclosure

Issuers SHOULD use BbsBlsSignature2020 proofs [[BBS-2023]] to enable Holders to present derived credentials disclosing only required claims. Verifiers MUST NOT require disclosure beyond their stated verification purpose and MUST document minimum required claim sets.

Pairwise DIDs for Object Identity

Implementations MAY use pairwise DIDs — distinct DIDs presented to different Verifiers for the same physical object — to prevent cross-Verifier correlation. Resolvers MUST support DID aliasing.

ExternalData Access Control

Resolvers and Verifiers MUST enforce the accessPolicy field:

Data Minimization

The evidence array SHOULD contain only data necessary for verification. Large payloads MUST be referenced via externalData. Evidence entries MUST NOT include PII about natural persons without explicit consent.

Immutability and Erasure Rights

Implementations in jurisdictions with data erasure requirements MUST implement Resolver-level access controls rather than modifying or deleting attestations. PII MUST be placed in holder-controlled or encrypted externalData so that access revocation effectively implements erasure without chain corruption.

Commercial Confidentiality

Issuers MAY encrypt sensitive claims using the intended Verifier's public key. Resolvers MUST store encrypted fields as opaque blobs and MUST NOT attempt decryption.

Security Considerations

Timestamp Manipulation Mitigation

Authority precedence is the primary conflict resolution cascade discriminator. A forged timestamp can only influence Tier 2, reached only when Issuers have identical authority precedence. The losing attestation is always preserved with supersededBy, making manipulation detectable in audit.

Issuer Impersonation

Mitigated by mandatory CertificationCredential validation at Phase 5, Trust Anchor ability to revoke compromised certifications via BitstringStatusList (max 5-minute cache), and cryptographic binding of every attestation to the Issuer's DID.

Antecedent Chain Breaks

Attestations with unresolvable antecedents are flagged chainIntegrity: "broken" and require manual investigation.

Custody Gap Attacks

Linear custody chain enforcement prevents insertion of Transfer attestations that skip over legitimate custody events.

Replay Attacks

Mitigated by UUID URN uniqueness and duplicate ID rejection at Phase 1.

DAG Depth Attacks

Normative DAG depth limit (64 hops), width limit (256 entries), and traversal timeout (30 seconds) bound computational cost.

Cyclic Antecedent Attacks

Resolvers MUST implement visited-ID cycle detection and reject cyclic graphs with rejected_cyclic_chain.

CertificationCredential Revocation Timing

The 5-minute revocation cache maximum limits the window during which revoked credentials may be accepted. Trust Anchors SHOULD implement emergency revocation procedures.

Appendix A: UORA JSON-LD Context

The canonical JSON-LD context is published at:

https://w3id.org/uora/contexts/core.jsonld
{
  "@context": {
    "@version": 1.1,
    "@protected": true,
    "id": "@id",
    "type": "@type",

    "UORAAttestation":             { "@id": "https://w3id.org/uora#UORAAttestation" },
    "UORAOriginAttestation":       { "@id": "https://w3id.org/uora#UORAOriginAttestation" },
    "UORATransferAttestation":     { "@id": "https://w3id.org/uora#UORATransferAttestation" },
    "UORATransformationAttestation": { "@id": "https://w3id.org/uora#UORATransformationAttestation" },
    "UORADispositionAttestation":  { "@id": "https://w3id.org/uora#UORADispositionAttestation" },
    "UORACertificationCredential": { "@id": "https://w3id.org/uora#UORACertificationCredential" },

    "eventType":    "uora:eventType",
    "antecedent":   { "@id": "uora:antecedent", "@type": "@id" },
    "authorizedBy": "uora:authorizedBy",

    "originType":       "uora:originType",
    "originLocation":   { "@id": "uora:originLocation", "@type": "@id" },
    "originDate":       { "@id": "uora:originDate", "@type": "xsd:dateTime" },
    "productionBatch":  "uora:productionBatch",
    "inputMaterials":   { "@id": "uora:inputMaterials", "@type": "@id", "@container": "@set" },

    "transferType":  "uora:transferType",
    "fromParty":     { "@id": "uora:fromParty", "@type": "@id" },
    "toParty":       { "@id": "uora:toParty", "@type": "@id" },
    "fromLocation":  { "@id": "uora:fromLocation", "@type": "@id" },
    "toLocation":    { "@id": "uora:toLocation", "@type": "@id" },

    "transformationType":    "uora:transformationType",
    "inputObjects":  { "@id": "uora:inputObjects", "@type": "@id", "@container": "@set" },
    "outputObjects": { "@id": "uora:outputObjects", "@type": "@id", "@container": "@set" },
    "inputQuantities":  "uora:inputQuantities",
    "outputQuantities": "uora:outputQuantities",
    "transformationLocation": { "@id": "uora:transformationLocation", "@type": "@id" },
    "processCertification":   { "@id": "uora:processCertification", "@type": "@id" },

    "dispositionType":             "uora:dispositionType",
    "dispositionLocation":         { "@id": "uora:dispositionLocation", "@type": "@id" },
    "environmentalCertification":  { "@id": "uora:environmentalCertification", "@type": "@id" },

    "certificationId":        { "@id": "uora:certificationId", "@type": "@id" },
    "trustFramework":         { "@id": "uora:trustFramework", "@type": "@id" },
    "verifiedAt":             { "@id": "uora:verifiedAt", "@type": "xsd:dateTime" },
    "authorityPrecedence":    "uora:authorityPrecedence",
    "authorizedAttestations": "uora:authorizedAttestations",
    "authorizedCategories":   "uora:authorizedCategories",
    "authorizedRegions":      "uora:authorizedRegions",

    "accessPolicy":   "uora:accessPolicy",
    "encryptedFor":   { "@id": "uora:encryptedFor", "@type": "@id" },
    "externalData":   "uora:externalData",
    "physicalBinding": "uora:physicalBinding",

    "epcisEventID":   "uora:epcisEventID",
    "epcisEventType": "uora:epcisEventType",
    "epcisBizStep":   "uora:epcisBizStep",

    "uora": "https://w3id.org/uora#",
    "xsd":  "http://www.w3.org/2001/XMLSchema#"
  }
}
        

References

Normative References

[[DID-CORE]]
Decentralized Identifiers (DIDs) v1.0. W3C Recommendation, 2022.
[[VC-DATA-MODEL-2.0]]
Verifiable Credentials Data Model v2.0. W3C Recommendation, 2024.
[[VC-DATA-INTEGRITY]]
Verifiable Credential Data Integrity 1.0. W3C Recommendation, 2024.
[[BITSTRING-STATUS-LIST]]
Bitstring Status List v1.0. W3C Recommendation, 2024.
[[BBS-2023]]
BBS Cryptosuite v2023. W3C Credentials Community Group Draft, 2023.
[[RFC2119]]
Key words for use in RFCs to Indicate Requirement Levels. Bradner, 1997.
[[RFC8259]]
The JavaScript Object Notation (JSON) Data Interchange Format. 2017.
[[ISO-8601]]
Date and time format. ISO 8601-1:2019.
[[NIST-SP800-57]]
Recommendation for Key Management. NIST SP 800-57 Part 1 Rev 5, 2020.

Informative References

[[EPCIS-2.0]]
GS1 EPCIS 2.0 Standard, 2022.
UORA Secure Physical Binding
UORA Secure Physical Binding Specification v1.0.