Disclosure doesn't cost you the signature

Disclosure doesn't cost you the signature

Every reader of a passport gets the same public data, and some get protected fields on top. The quieter question is whether those extra fields bring their proof with them. We sign every field on its own, so a disclosed field checks against a public key - offline, with no call back to us.

A Digital Product Passport does not show everyone the same thing. A shopper sees the public data. A repairer or a refurbisher sees more. A market-surveillance authority sees everything. That much is settled, and the European standards now spell it out.

The interesting question is quieter: when protected fields are disclosed to a reader on top of the public data, can they prove that those particular fields are genuine? Or do they just have to trust that the platform picked them correctly and passed them on unchanged?

For most platforms, the honest answer is trust. We built ours so the answer is proof, not only for the public fields but for every field that arrives through disclosure. Here is why that distinction matters, and why we took the harder road to get it.

Everyone meets the access rule the same way

EN 18239, the European standard for access-rights management, security and confidentiality in a DPP, says access has to be controlled per data element: each field has a rule for who may see it. It is the right requirement, and it is not hard to satisfy. What status these standards actually carry, we broke down in harmonised standards.

The common way to satisfy it is server-side filtering. The server knows who is asking, looks up what they are allowed to see, and returns exactly that subset. Access control: done. The standard asks for nothing more.

There is one catch the standard does not concern itself with. The subset arrives unsigned. The reader gets a view assembled for them and has to take it on faith that the server selected honestly and changed nothing on the way out. For a public leaflet, fine. For a number a refurbisher is about to price a used battery on, that is a lot of faith.

Where a single signature runs out

The obvious fix is to sign the data. For the two ends of the range, a plain signature works well: sign the public view, sign the full record, and each verifies against a public key with no server in the loop. How that works in detail is in signatures and certificates in the DPP.

The middle is where it breaks. A whole-document signature covers exactly one set of fields, the ones present when it was signed. Disclose one protected field to an entitled reader and that field sits outside the signed set, arriving uncovered. Sign the full record up front instead and the signature covers everything, but then you would have to show everything to everyone.

So the tiers in between, the ones for a repairer, an insurer, a recycler, fall through the gap. To sign every possible combination of who-sees-what in advance, you would need a separate signed document for each combination, and the number of combinations explodes with every access group you add. Nobody does that. They fall back to the unsigned server filter, and the middle tier goes back to running on trust.

Signing each field on its own

There is a better construction, and it is the one we are building the platform on. Instead of signing the finished document as one block, the issuer commits to each field independently in a single signing pass (for the standards-minded, this is the W3C ecdsa-sd-2023 selective-disclosure proof).

Every view starts from the public core

Every view now starts from the same public fields. Whatever a reader gets beyond them is added field by field, and each of those fields still checks back to the issuer’s public key, offline, with no re-signing and no trust in whoever assembled the view. The fields they are not entitled to are simply absent. Not blacked out, just not there, and nothing about them leaks.

Why “unbroken” is the whole point

Picture a notary who certifies each paragraph separately rather than the letter as a whole. Everyone receives the public letter. Anyone entitled to more receives the additional paragraphs too, each still carrying the same notary’s seal. Under the common approach the platform retypes those paragraphs for you, and what arrives carries nothing but its word.

Why “unbroken” carries the weight here is worth one more sentence. An intact seal does not say the content is true. It says: this is exactly what the issuer wrote, and not one character has changed since. That takes everyone who merely passed the document along out of the trust question - the cache, the network, the archive, us. Who handed you the passport stops mattering.

And a seal is binary. It holds or it does not; there is no half-broken seal. When one breaks it does not tell you which sentence was altered, only that you can no longer trust the sheet. So it is not a difference of degree whether the additional fields reach you with their seal or without it. Without one they are not slightly weaker evidence, they are no evidence at all.

Both constructions, side by side

You can check all of this yourself. The Transpareo Time Machine is our open-source viewer for product passports: it leafs through a passport’s version history and recomputes every signature in the reader’s own browser, without asking a server of ours. Two example passports run in it publicly. The passport of a t-shirt carries a whole-document signature; the passport of a battery carries per-field disclosure.

Both are open W3C specifications: eddsa-jcs-2022 for the whole-document signature, ecdsa-sd-2023 for per-field disclosure. Anyone who wants to implement them can. The effort is the reason many will not: the whole-document signature is considerably cheaper to build and to run, and for a passport carrying only public data it is enough.

That the Time Machine handles both is deliberate, and it stays that way. It belongs to no platform. A verifier that accepted only the more expensive construction would be a tool for us and for nobody else.

Who the protected fields are disclosed to

It is worth asking who is actually shown anything beyond the public data. Not the casual shopper, who gets the public passport. It is the refurbisher deciding what a used pack is worth, the insurer pricing a risk, the recycler sorting chemistries, the authority building a case. These are the readers making decisions with money or safety attached.

Those are also the fields that arrive uncovered under the common approach. The people with the most reason to want cryptographic assurance go without it for precisely the fields their decision rests on.

We think a verification badge should mean the same thing for all of them. “Verified by Transpareo” on a repairer’s extended view certifies what it certifies on a shopper’s public passport: every field shown came from the issuer and has not been touched since. A seal that only covers the public fields is half a seal.

Beyond what the standard asks

We will be straight about this: the standard does not require any of it. EN 18239 asks for access to be controlled, and a server-side filter controls access perfectly well. Making the disclosed fields cryptographically verifiable too is something we choose to do on top, not a box the regulation makes us tick.

That is exactly why it is worth writing down. It would be easy to meet the letter of the standard, ship the server filter, and call the tier handled. We would rather the guarantee hold everywhere the badge appears, because the whole reason a passport is signed is so nobody has to trust the platform. Carving out the middle tier as an exception quietly puts back the trust the signature was there to remove.

The same design lets a field be forgotten

Committing to each field on its own buys a second property, and this one European law actually requires. The General Data Protection Regulation gives people the right to have personal data erased. A record signed as one block cannot honour that without shredding its own signature.

Because each field stands alone here, a single field can be removed while everything else still verifies. If personal data ever lands in a passport by mistake, it comes out cleanly and the passport stays valid: no re-issuing, no broken history. The regulatory fields the law tells us to keep stay put; anything erasable can be erased on request, even years later.

Still one ordinary passport

None of this turns the passport into a special object only our tools can open. It stays a JSON-LD Verifiable Credential, the format the web-standards world is converging on, and the same shape the UN Transparency Protocol and the wider W3C ecosystem use.

So the passport a shopper scans in a browser is the same object a data-space partner can ingest, and any standards-compliant verifier can check it, not only ours. The extra assurance costs the reader nothing and locks nobody in.

Why this is technically hard

First, so no false impression takes hold: we did not invent the construction. ecdsa-sd-2023 is a public W3C specification, the cryptography behind it is not ours, and anyone who wants to implement it can read it up. The hard part is not having the idea. The hard part is building it so that a passport still verifies in ten years. That is where the work sits, and there is something useful to say about it.

The difference sounds small but it moves the ground you stand on: an ordinary signature computes over the bytes of a document. Selective disclosure computes over its statements. Before signing, the passport is put into a canonical form in which every entry is its own free-standing statement. Only that makes it possible to leave one statement out without damaging the others.

With it you inherit a problem a byte signature does not have: the same canonical form has to come out again exactly, ten years later. Not roughly, character for character, or no proof matches. Three things stand in the way, and all three are inconspicuous.

Numbers lose their type. Write a number as plain JSON and what kind of number it was gets lost along the way. A value like 2.0 comes back as 2 after a round trip through JSON. The same thing to a human, a different statement to the canonical form, and verification fails.

Names are not yet meanings. For the canonical form to exist, every field name has to resolve to an unambiguous meaning. If one is missing, the field silently disappears in the conversion. It is still in the passport, but the proof does not cover it, and nobody notices.

Meanings usually live on the network. That mapping sits in a vocabulary most tools fetch over the network at verification time. Doing so makes your passport’s verifiability depend on someone else’s address still answering in ten years, and answering unchanged.

How we solved it

We closed all three at the root rather than catching them later.

Types. Every value is written with its type, and publication aborts the moment a single untyped number turns up in the canonical form. The error lands where it costs one line, instead of surfacing years later as an unexplained verification failure.

Vocabularies. Every vocabulary a passport refers to is held locally and never fetched over the network. An unknown address is a hard stop at signing time, not a quiet fallback to an empty result.

Identifiers. Every node in the document carries a stable identifier, so the canonical form stays reproducible instead of handing out fresh placeholder names on each run.

The most delicate part sits in Bring Your Own Key. Each issuance needs an additional, short-lived key that signs the disclosable fields individually. The issuer generates and discards that key itself. If we held it, we could invent individual fields after the fact, and the independence of the issuer’s signature would be a claim rather than a fact. We verify the returned proof against the registered public key before trusting it.

Every passport carries two such proofs, one from the issuer and one from Transpareo, and each is derived independently for a reader’s view. Two signatures, two mutually independent authorities, for a single disclosed field as much as for the whole record.

For us this effort lands in the right place. We did not add verification late; the platform was built around it from the first version. Every passport is signed on publish and chained to the version before it. The immutable ten-year archive is in place and takes effect as soon as the passports are registered with the EU DPP register. Signing each field instead of the whole block is an extension of that core, not a bolt-on to something that was never designed for it.

Where we stand

Strip it back and the choice is simple. You can disclose protected fields and ask the reader to trust your filter, which meets the standard. Or you can disclose them and hand over the proof along with them, which meets a higher bar we think those fields deserve.

We picked the proof, for every reader, because a seal should mean one thing no matter who is looking. If you want to see it work: both demos linked above verify right in your browser, offline, against nothing but a public key.

Updates on access tiers and proofs

Selective disclosure, signatures and how the DPP standards are moving - a compact monthly briefing to your inbox.