Security & cryptography
Anyone who comes across a passport, whether a consumer, a recycler or a market-surveillance authority, needs to know whether it is genuine, unaltered and issued by the company it names. The core answers that with open, audited cryptography, and the answer does not depend on Odal being online or existing.
A passport is signed
Section titled “A passport is signed”When a passport is published, the validated data is signed as a JSON Web Signature with the issuer’s own Ed25519 key, twice: once over the full passport and once over its public view. Each signature covers the exact bytes it signs, so changing a single value afterwards makes verification fail. A reader does not have to trust a database entry; the passport carries its own proof. (W3C Verifiable Credentials do something else: they are what a reader presents to see restricted parts. See Access control.)
The issuer’s domain is the trust root
Section titled “The issuer’s domain is the trust root”A signature is only useful if you know whose key made it. The core uses did:web for identity: the issuer publishes their public key as a small document at a fixed address on their own domain (/.well-known/did.json). Verifying a passport is then an ordinary web lookup: fetch the issuer’s key and check the signature.
Trust comes from DNS and HTTPS, the same infrastructure that secures the issuer’s website. There is no blockchain, no central authority that has to stay online, and no role for Odal in verification. The signature proves authenticity (the named issuer signed it), integrity (it has not been altered) and binding (it refers to the specific product). It does not prove that the issuer’s figures are correct. The core proves who said what; it cannot check whether it is true.
Rotating keys
Section titled “Rotating keys”Signing keys change over time: one is retired and a new one takes over. Retired keys stay in the issuer’s identity document, and every signature names the exact key that produced it. A new key signs new passports, and passports signed with an older key still verify against that older key.
A passport has to stay verifiable for as long as the law keeps it available: under ESPR at least the product’s expected lifetime, and ten years after placing on the market under the toy, detergent and construction rules. Rotating a key never invalidates anything already published, and never requires reprinting a label.
Keys are encrypted at rest
Section titled “Keys are encrypted at rest”A signing key is generated from the operating system’s randomness. It is never derived from a password, so it cannot be guessed. The private key is stored encrypted:
- The passphrase that unlocks the store goes through Argon2id, a slow, memory-hard function, to produce the encryption key. This makes guessing the passphrase by brute force impractical, even with the file in hand.
- That key encrypts the store with AES-256-GCM, an authenticated cipher, so the contents are hidden and any modification is detected.
- A separate integrity check (HMAC) covers the whole file, so tampering is detected, including an attempt to downgrade the protection to a weaker scheme.
- Key material is wiped from memory as soon as it is no longer needed.
The encrypted key file is useless without the passphrase. Where the store lives and how a running node protects it is covered in Operating a node securely.
Product-group rules run in a sandbox
Section titled “Product-group rules run in a sandbox”The rules that decide whether a product’s data is compliant change with each product group and each regulation, so they are kept out of the trusted core. A product group’s compliance logic is compiled to WebAssembly and runs in a sandbox with a short list of capabilities. It has no filesystem and no network: it cannot read or write a file or open a socket. Apart from computing on the data it is given, a plugin can only write a log line, read a clock fixed to one instant for the whole call, and draw OS randomness. None of that reaches the signing key, the database or any other passport. Execution is limited too, with a fixed memory cap and a metered CPU budget, so a plugin that misbehaves is stopped. Before loading a plugin, a node checks its signature against the pinned publisher key; the only way round that is an explicit override, honoured only on a development node and logged as a warning (see Product groups & plugins).
Judging data and signing it are therefore separate. A buggy or even hostile product-group rule can fail a validation, but it cannot touch the signing key, change a passport or forge a signature. New regulations arrive as new sandboxed plugins, and none of the guarantees on this page depends on trusting them. The exact runtime limits are in Operating a node securely.
Linking the passport to the physical product
Section titled “Linking the passport to the physical product”The QR code printed on a product is a GS1 Digital Link. The node builds it from the signed passport’s own verified fields each time it is served, never from a stored link that could be edited. If the passport’s signature does not verify, no QR code is produced: the node refuses to print a code for data it cannot prove.
The serial number on the label is derived from the passport’s identity. It is fixed-length, GS1-conformant and non-sequential, so a public label reveals nothing about production volumes. Everything printed on the product traces back to the signed passport: a tampered passport cannot get a new label, and the label carries nothing a verifier cannot check.
Suspected vulnerabilities go to security@odal-node.io under coordinated disclosure, never to a public issue first.
Read next
Section titled “Read next”- What the core does: the library these guarantees protect.
- Standards & interoperability:
did:weband the open standards verification relies on. - What Odal can and cannot see: exactly what data Odal can and cannot reach.
- Operating a node securely: how a running node protects keys and access in production.
Information on this site is not legal advice. Legal noticePrivacy policy