The digital product passport under ESPR, Articles 9 to 13
The Ecodesign for Sustainable Products Regulation, Regulation (EU) 2024/1781, sets up the EU Digital Product Passport. Chapter III of the regulation, Articles 9 to 15, defines what a passport is, how it's built and how authorities find it.
ESPR is a framework regulation. It doesn't list the data fields for a specific product. Delegated acts adopted for each product group set the product-specific requirements, including which information the passport must hold and when the obligation starts for that group.
Article 9: the passport obligation
Where a delegated act requires one, a product can only be placed on the market or put into service with a digital product passport. The delegated act sets the information the passport carries, which can cover materials, substances of concern, repairability, recycled content and environmental footprint.
ESPR places the passport on the economic operator who places the product on the market. Keeping its information accurate, complete and up to date is that operator's job.
Article 10: requirements for the passport
The passport is connected through a data carrier, such as a QR code, to a persistent unique product identifier. The data carrier sits on the product, its packaging or its accompanying documentation, as the delegated act specifies.
The passport data must be based on open standards, use an interoperable format and be machine-readable, structured and searchable. A customs officer, a recycler and a consumer should all be able to read the same passport without a proprietary client.
Article 11: technical design and operation
The passport runs as a decentralised system. The economic operator responsible stores the passport data itself or through authorised digital product passport service providers acting on its behalf. There is no single EU database holding every passport.
Access rights are set per product group in the delegated act. Consumers, economic operators and authorities such as market surveillance and customs can each be given a different view of the same passport. The passport must also stay available for the period the delegated act sets.
Article 12: unique identifiers
Every passport keys off identifiers. The unique product identifier names the model, the batch or the individual item, depending on the granularity the delegated act requires. Unique operator identifiers and unique facility identifiers name who made the product and where.
Article 13: the digital product passport registry
The Commission sets up and manages a digital product passport registry. The registry stores the unique identifiers that link to each passport, so authorities can confirm a passport exists and locate it. The passport content itself stays with the economic operator or its service provider.
Articles 14 and 15 then add a public web portal for passport data and customs controls linked to the registry. For batteries, Regulation (EU) 2023/1542 sets a separate battery passport, which applies from 18 February 2027 for LMT batteries, industrial batteries above 2 kWh and EV batteries.
What this means for evidence
Decentralised storage puts the integrity question on the operator. When a market surveillance authority reads a passport in 2032, it needs a way to tell that the carbon footprint figure is the one published in 2027, and to see every change in between. A hash anchored at publication answers that question without moving the data anywhere.
CBAM: embedded emissions and verified declarations
The Carbon Border Adjustment Mechanism, Regulation (EU) 2023/956, puts a carbon price on the embedded emissions of certain goods imported into the EU, including iron and steel, aluminium, cement, fertilisers, hydrogen and electricity.
The transitional period ran from 1 October 2023 to 31 December 2025. Importers filed quarterly CBAM reports on embedded emissions without buying certificates.
The definitive period started on 1 January 2026. Imports of CBAM goods now go through authorised CBAM declarants, who file an annual CBAM declaration and surrender CBAM certificates that match the embedded emissions of the goods they imported. The embedded emissions in the declaration are verified by an accredited verifier. Thresholds and timing details are subject to the current simplification amendments, so check the consolidated text for your import volumes.
The evidence a CBAM file needs
- Installation-level emissions data. Direct and indirect emissions per installation and production route, with the activity data and the period.
- Supplier communications. The emissions reports and templates that operators outside the EU send to the importer, and every revised version.
- Verification reports. The accredited verifier's report on the embedded emissions, tied to the exact dataset it covered.
- Calculation records. How the declarant moved from installation data to embedded emissions per tonne of imported goods.
The weak point is usually the supplier file. A spreadsheet emailed in March and corrected in May leaves two versions with the same name. Hashing each received file on arrival shows which bytes the verifier saw.
CSRD: ESRS E1, ESRS S1 and an audit trail that can be assured
The Corporate Sustainability Reporting Directive, Directive (EU) 2022/2464, requires in-scope undertakings to publish a sustainability statement under the European Sustainability Reporting Standards and to obtain limited assurance on it.
Which companies report, and from which financial year, is subject to the current phase-in. The Omnibus simplification package changed both scope and timing, so confirm your own position against the text in force.
ESRS E1 and ESRS S1
ESRS E1 covers climate change: gross Scope 1, 2 and 3 greenhouse gas emissions, energy consumption, transition plans and climate targets. ESRS S1 covers the undertaking's own workforce: headcount, employee characteristics, working conditions, health and safety, and equal treatment.
Both standards draw on operational systems that change during the year. Energy invoices are reissued, HR records are corrected and emission factors are updated.
What an assurance provider asks for
- Data lineage. Which source records feed each reported datapoint.
- Versions. The exact state of each source on the date the figure was calculated.
- Change history. Who changed what, and when, between the draft and the published statement.
An assurance provider can sample a datapoint and trace it back to a source file. If that file's hash matches a version anchored before the statement was signed, the provider has evidence that the source was not edited afterwards.
Mapping obligations to evidence artifacts
Each row maps one obligation to the artifact that evidences it, the Rekord Kloud mechanism that makes the artifact tamper-detectable, and the party who checks it.
| Obligation | Evidence Artifact | Rekord Kloud Mechanism | Verifier |
|---|---|---|---|
| ESPR Art. 9 and 10: accurate, up-to-date passport data | Passport record as canonical JSON, one revision per update | SHA-256 of the canonical bytes, one appended version per update, anchored Merkle root | Market surveillance authority, customs |
| ESPR Art. 11: data held by the operator or a service provider | Supporting files behind each passport field (material declarations, test reports) | Per-file SHA-256, hashed verbatim, batched into the version's Merkle tree | Notified body, market surveillance authority |
| ESPR nested products: component passports | Component records inside the product record | Recursive trees: each child version's root is a leaf of its parent | Recycler, repairer, authority |
| CBAM: verified embedded emissions in the declaration | Installation emissions data, supplier communications, verification report | Per-file SHA-256 on receipt, append-only versions, inclusion proof per file | Accredited verifier, competent authority |
| CSRD ESRS E1: Scope 1, 2 and 3 emissions | Energy invoices, fuel records, emission factor tables, calculation workbook | Version per reporting cut-off with its anchored root, re-checked live at verification | Assurance provider |
| CSRD ESRS S1: own workforce datapoints | HR headcount extracts, health and safety logs | Hash of each extract as submitted; the personal data stays off-chain | Assurance provider |
| Battery Regulation (EU) 2023/1542: battery passport (optional) | Battery passport records and their revisions | Anchored root for each revision | Market surveillance authority |
Worked example: hashing, canonical JSON, a Merkle root and an inclusion proof
The example below is illustrative. The product, the company and the figures are invented, but every hash is real and computed when this page is built, so you can reproduce each value with any SHA-256 tool.
Step 1: hash each supporting file verbatim
A gearbox manufacturer keeps 2 supporting files for one passport. The first is a supplier
emissions extract; the second is a material declaration. Here are their exact contents, UTF-8
encoded, with every line ending in a single line feed (0x0A).
installation_id,period,direct_tco2e,indirect_tco2e,output_t
INST-0091,2026-Q3,1840,312,5200
component,material,mass_kg,recycled_pct
housing,steel,412,34
winding,copper,18,0
Each file is hashed exactly as submitted. Nothing is trimmed, reordered or re-encoded first, so a re-export that changes 1 byte, such as a CRLF line ending, gives a different hash.
Step 2: canonicalize the passport record with RFC 8785
The passport record is structured data, and 2 systems can write the same data in different byte orders. Here is the record as an upstream system wrote it, with unsorted keys and uneven spacing.
{
"productId": "urn:example:dpp:GBX-7300-000042",
"schema" : "example-dpp-record/1",
"manufacturer": "Example Gearworks GmbH",
"carbonFootprint": { "value": 2875, "unit": "kgCO2e" },
"materials": [
{ "name": "steel", "massKg": 412, "recycledPct": 34 },
{ "name": "copper", "massKg": 18, "recycledPct": 0 }
],
"batch": "2026-W41"
} RFC 8785, the JSON Canonicalization Scheme, defines one byte-exact form: keys sorted recursively, no insignificant whitespace, a fixed number format and UTF-8 encoding. Here is the same record in canonical form.
{"batch":"2026-W41","carbonFootprint":{"unit":"kgCO2e","value":2875},"manufacturer":"Example Gearworks GmbH","materials":[{"massKg":412,"name":"steel","recycledPct":34},{"massKg":18,"name":"copper","recycledPct":0}],"productId":"urn:example:dpp:GBX-7300-000042","schema":"example-dpp-record/1"}
The record holds only ASCII text and integers, so a key-sorted JSON.stringify gives
the RFC 8785 output. Records with floating-point numbers or non-ASCII keys need a full
implementation of the scheme.
The difference matters. The 354-byte "as received" text hashes to
778304ce61f90eab00e68817baa931068f0028ed9a2b3efc01d26523cf147e15, while the 294-byte canonical form hashes to
be62c9fc532dff7ed01221d5a72b16ad40da28f79af1e5d26965888013311f6d. Same data, 2 hashes. The operator canonicalizes the record before
it submits it, so every party that holds the data computes the second value.
Step 3: the 3 leaf hashes
6c91b88a29db30c6b4428f99e46545643c9afcd6f060234e2ea47d6e984f41d7 supplier-emissions.csv (92 bytes)
2a9e29003d56594cde88af30e49c39d2e865ccf44b39fb771a98727e08754008 material-declaration.csv (81 bytes)
be62c9fc532dff7ed01221d5a72b16ad40da28f79af1e5d26965888013311f6d passport-record.json (294 bytes) Step 4: build the Merkle root
Rekord Kloud builds the tree the same way every time:
- each leaf hash is trimmed, lowercased and stripped of any
0xprefix, and empty values are dropped; - duplicate hashes are removed and the remaining leaves are sorted in ascending order;
- consecutive nodes are paired, and a trailing odd node pairs with itself;
- each pair is sorted, hex-decoded, concatenated and hashed with SHA-256, level by level, until one root remains.
With 3 leaves, the first 2 sorted leaves form node N1. The third leaf is the odd node, so it pairs with itself to form N2. N1 and N2 are then sorted and hashed into the root.
root = SHA-256( sort(N1, N2) )
= 1ce160abe4f99eace29d08dabeb8b8c573dc56f5b01bfae1ffffb36aef19413c
N1 = SHA-256( 2a9e2900… || 6c91b88a… )
= c10bd8d850c310fdd984b6de322c4ed946d6236385478dfe383c4a796c0cf468
N2 = SHA-256( be62c9fc… || be62c9fc… ) odd node, paired with itself
= c37d1dbd29de2596cc2be81b062d49c3a316a1a8114a0e5a47b21c5fec4f0657
leaf 1 = 2a9e29003d56594cde88af30e49c39d2e865ccf44b39fb771a98727e08754008 material-declaration.csv
leaf 2 = 6c91b88a29db30c6b4428f99e46545643c9afcd6f060234e2ea47d6e984f41d7 supplier-emissions.csv
leaf 3 = be62c9fc532dff7ed01221d5a72b16ad40da28f79af1e5d26965888013311f6d passport-record.json
The || sign means byte concatenation of the 32-byte decoded values, so each
SHA-256 input is 64 bytes. Frozen golden test vectors keep this procedure byte-identical across
Rekord Kloud releases.
Step 5: the inclusion proof for one file
An auditor who only needs the supplier emissions file doesn't need the other 2 files. The inclusion proof gives the sibling hash at each level between that leaf and the root.
{
"file": "supplier-emissions.csv",
"leaf": "6c91b88a29db30c6b4428f99e46545643c9afcd6f060234e2ea47d6e984f41d7",
"siblings": [
{
"level": 0,
"hash": "2a9e29003d56594cde88af30e49c39d2e865ccf44b39fb771a98727e08754008"
},
{
"level": 1,
"hash": "c37d1dbd29de2596cc2be81b062d49c3a316a1a8114a0e5a47b21c5fec4f0657"
}
],
"root": "1ce160abe4f99eace29d08dabeb8b8c573dc56f5b01bfae1ffffb36aef19413c"
} This is a sorted-pair SHA-256 tree. Each pair is sorted before hashing, so the proof carries no left or right position flags, only the sibling hashes in level order.
Step 6: verify
- Hash the file bytes you received with SHA-256 and compare the result with
leaf. - For each sibling in level order, sort the pair of your current hash and the sibling, hex-decode both, concatenate them and hash the 64 bytes with SHA-256.
- Compare the final value with
root. - Compare
rootwith the Merkle hash anchored for that version, in the Proof Console or in a public explorer for the chain.
step 1 h = SHA-256(file bytes) = 6c91b88a29db30c6b4428f99e46545643c9afcd6f060234e2ea47d6e984f41d7
step 2 h = SHA-256(sort(h, sib[0])) = c10bd8d850c310fdd984b6de322c4ed946d6236385478dfe383c4a796c0cf468
step 3 h = SHA-256(sort(h, sib[1])) = 1ce160abe4f99eace29d08dabeb8b8c573dc56f5b01bfae1ffffb36aef19413c
step 4 h == anchored root = true If step 4 matches, the file was part of that version when it was anchored and its bytes are unchanged. If any byte of the file changed, step 1 gives a different hash and every later step fails.
On-chain anchoring, versions and nested passports
Only the Merkle root goes on-chain. A root is a 32-byte SHA-256 value that holds none of the passport content, so supplier data and workforce records stay with you.
Rekord Kloud anchors to VeChain by default, and to Litecoin and BSV, where the root is written
into an OP_RETURN output. Each anchor records its confirmations and the anchored
Merkle hash.
When you verify, the version service re-checks every anchor live against the chain. The Proof Console links each anchor to a public explorer: explore.vechain.org for VeChain, a Litecoin explorer, and whatsonchain.com for BSV.
Append-only versions
An update to a passport appends a new version with its own root. Earlier versions and their anchors stay in place, so an authority can open the 2027 version next to the 2029 version and see what changed. Any edit to an anchored record is tamper-detectable.
Recursive trees for nested products
Product passports nest: a component has its own records inside the record of the product that contains it. Recursive Merkle trees follow the same shape, with each child version's root sitting as a leaf in its parent. A gearbox root can sit as a leaf in a wind turbine root, and each component stays provable on its own.
Rekord validated a wind turbine lifecycle DPP with the Advanced Manufacturing Research Centre (AMRC), modelling thousands of recursive nested components that require simultaneous ESPR and CRMA passports.
Who carries the obligation
Rekord provides the infrastructure. The obligation stays with you.
- The economic operator stays responsible for the digital product passport under ESPR, for its content and for its accuracy.
- The authorised CBAM declarant stays responsible for the CBAM declaration, the embedded emissions it reports and the certificates it surrenders.
- The reporting undertaking stays responsible for its CSRD sustainability statement and for the assurance engagement around it.
Rekord Kloud and the Proof Console are built by Rekord AG in Zug, Switzerland. Rekord AG provides tamper-detectable evidence infrastructure: SHA-256 hashes, versioned Merkle roots and on-chain anchors that show a record existed in a given version and hasn't changed since.
The legal sufficiency of a record, and the truth of the figures in it, stay with the party that produced them. Kloud shows the record is byte-identical to what was anchored; your verifier and your counsel judge what it says. For the full architecture, see how Rekord works and the product page for Rekord Kloud.