tExtended — UNTP Identity Resolver Demonstrator

Exploring digital product passports and supply chain transparency for extending the useful lifecycle of textile fibres

Open scanner →

What this demonstrator shows

This system is a working implementation of the UN Transparency Protocol (UNTP) Identity Resolver specification, built to explore how digital product passports, traceability events, and conformity credentials can be created, managed, and accessed across a textile supply chain.

The central question it addresses: given a physical product — a garment, a fibre batch, a recycled material — how can different stakeholders access the right information about it, in a standardised way, regardless of which system originally created that information? The UNTP Identity Resolver is the discovery layer that makes this possible.

The UNTP Identity Resolver

The Identity Resolver (IDR) implements the Discover–Resolve–Verify (D-R-V) workflow defined in the UNTP specification: given an identifier on a physical product, a client discovers what verifiable data exists about it, resolves the links to that data, and verifies the authenticity of the credentials retrieved.

This demonstrator implements some of the features from the IDR specification and related UNTP best practices:

IDR-02
IETF RFC 9264 linksets — structured, typed link responses mapping identifiers to credential URLs. One data carrier, many links.
VD-01
Variant-based disclosure — different stakeholders access different subsets of credential data based on their access role, using a single identifier and a single QR code.
IDR-11
Primary and secondary resolvers — a query about a serialised item returns links at both item level and product class level simultaneously, reflecting real-world identifier governance structures.
IDR-08
Language negotiation — the resolver respects HTTP Accept-Language headers, returning credentials in the requester's preferred language where available.
IDR-04
ISO/IEC 18975 Digital Link — QR codes encode resolver URLs directly. 1D barcodes are normalised to resolver URLs via GS1 application identifier parsing, demonstrating the identifier normalisation pipeline.
IDR-13
W3C Verifiable Credentials (vc+jwt) — all credentials are signed using Ed25519 keys under a did:web DID, making them independently verifiable against the issuer's published DID document.
IDR-14
/.well-known/resolver — the resolver declares its capabilities per RFC 8615, enabling conformant client discovery before dereferencing any links.

Variant-based disclosure and access roles

A core focus of this demonstrator is the variant-based disclosure pattern defined in the UNTP best practices. Rather than using cryptographic selective disclosure mechanisms such as BBS+ signatures or SD-JWT — which enable selective disclosure within a single credential — UNTP takes a simpler approach: multiple complete credential variants are pre-computed and stored, each containing the claims appropriate for a given access role. The Identity Resolver routes requests to the correct variant based on the accessRole query parameter.

Each credential variant contains full claims for the requesting role, plus claim stubs — entries without a declaredValue but with an accessRole property — indicating that additional data exists for other roles. This satisfies UNTP requirement VD-03 (claim discovery): a recipient can see what data exists without being able to access it.

This demonstrator uses four access roles:

Anonymous

Public consumer, e.g. someone scanning a product in a shop. Sees headline sustainability metrics, basic certifications, and care instructions.

Carbon footprint · water use · recyclability · GOTS status · care instructions
Customer

Product purchaser or business partner. Sees all public claims plus supply chain sourcing details and product specifications.

+ Fibre composition · yarn origin · shrinkage data · production country
Regulator

Compliance authority or auditor. Sees all public claims plus detailed environmental assessments, chemical compliance, and labour audit results.

+ Full GHG breakdown · water by phase · REACH · OEKO-TEX · SMETA audit
Recycler

End-of-life handler. Sees all public claims plus dye chemistry, finishing treatments, and disassembly guidance relevant to safe recycling.

+ Dye chemistry · finishing treatments · hardware attachments · chemical hazards
Note on role definitions: The UNTP specification does not define a normative set of access roles. The roles used here — Anonymous, Customer, Regulator, Recycler — are illustrative, drawn from examples in the variant-based disclosure best practice document. A real deployment would define roles appropriate to its governance context, sector, or regulatory requirements. The role URIs (e.g. untp:accessRole#Regulator) are referenced from the UNTP vocabulary namespace but their semantics and the process for verifying role membership are left to implementers.

Primary and secondary resolvers

The UNTP IDR specification defines a delegation pattern for cases where identifier schemes operate at a coarser granularity than the data that needs to be linked. A scheme register such as GS1 manages product class identifiers (GTINs) but has no knowledge of individual serialised items. Manufacturers manage serialised item data independently.

When a client queries a serialised item identifier, a conformant primary resolver returns a multi-anchor linkset: links about the specific serialised item at item level, and links about the product class at class level, in a single response. This demonstrator implements this pattern — querying a serialised battery identifier returns both unit-specific data (individual cell test results, component serial numbers, manufacturing batch) and product-class data (material composition, disassembly guide, emissions assessment) in one linkset response, with item-specific claims visually distinguished in the scanner interface.

If a serialised item has no registered entry, the resolver falls through gracefully to the product class — reflecting the real-world situation where not all physical units have item-level digital passports attached.

Try it

The scanner at /scan/ accepts QR codes, 1D barcodes via GS1 element string normalisation, and manual identifier input. Selecting a role before scanning demonstrates variant-based disclosure. Also automatic language negotiation is demonstrated.

The raw resolver API is accessible directly:

GET /01/{gtin} Product class linkset
GET /01/{gtin}/21/{serial} Serialised item linkset — returns both item and class anchors
GET /01/{gtin}?accessRole={roleURI} Role-filtered linkset — returns only variants matching the requested role
GET /01/{gtin}?language={lang} Language-filtered linkset — returns only variants matching the requested language
GET /.well-known/resolver Resolver description file per RFC 8615 and ISO/IEC 18975
GET /.well-known/did.json Issuer DID document — contains the Ed25519 public key for credential verification

Implementation

The demonstrator is built with a standard Python web stack. Credentials are signed using Ed25519 keys via the Python cryptography library and encoded as vc+jwt per the W3C Verifiable Credentials Data Model 2.0. The did:web DID method is used for issuer identity, with the DID document served at /.well-known/did.json. No external wallet infrastructure, DID registry, or ledger is required.

Python 3.12 Django 6 Django REST Framework SQLite Gunicorn Nginx Ed25519 / cryptography PyJWT did:web vc+jwt IETF RFC 9264 ISO/IEC 18975

Future work

Access role verification

This demonstrator trusts the accessRole query parameter without verification — any client can request any role. A production system would require the requester to prove role membership, via a Digital Identity Anchor credential, a shared secret embedded in product packaging, or DID authentication. The UNTP Decentralised Access Control specification defines the framework; integration with this resolver is future work.

In-browser credential verification

The scanner currently decodes and displays JWT payloads without cryptographically verifying the signature against the issuer's DID document. A complete implementation would fetch the DID document, extract the public key, and verify the Ed25519 signature before displaying any claims — making the Verify step of D-R-V fully operational in the client.

Credential lifecycle and post-issuance events

The UNTP IDR specification defines an edit link relation pattern allowing downstream actors to append new links to an existing identifier's linkset — for example, a recycler posting a Digital Traceability Event after processing a garment. This would enable a full lifecycle view: from production through sale, repair, resale, and end-of-life recycling, all linked to the same identifier.

Batch-level identifiers for textiles

Unlike batteries, individual garments are rarely serialised. Batch-level identifiers — identifying a production run rather than a single item — may be more appropriate for textile traceability. The IDR pattern supports this without modification, but the governance model for batch identifier issuance and the granularity of claims at batch versus item level warrants further investigation.

Integration with existing industry systems

The secondary resolver pattern allows a SaaS DPP platform or existing product information system to integrate with a scheme register's primary resolver without replacing it. Experimenting with real industry systems — connecting this resolver as a secondary resolver to an existing GS1 or sector-specific registry — is a natural next step for industrial partner engagement.

Sector-specific role taxonomy

The UNTP specification leaves role definitions to sector profiles and extension communities. Developing a textile-specific role taxonomy — defining which roles exist, what they mean, how they are governed, and how role membership is verified — is an open research and standardisation question directly relevant to the tExtended project scope.