QR code delivery
2 min read · Guides
QR code delivery
This guide covers how CNML certificates are delivered to instruments via QR codes, and how the passport endpoint serves the public view.
The delivery flow
For non-SMART instruments (instruments without a network interface), the manufacturer prints a QR code on the device body. The QR code encodes the passport URL:
https://www.oimlsmart.org/cnml/passport/<instance-cert-id>
https://www.oimlsmart.org/cnml/passport/<instance-cert-id>
A market-surveillance officer scans the QR code with a phone or tablet. The passport page loads and displays:
- The device identity (manufacturer, model, serial number)
- The OIML Recommendation the instrument is approved under
- The certificate chain (instance, model, IA, root)
- The certificate status (valid, revoked, expired)
- A link to the full verification pipeline
The passport endpoint
The passport endpoint serves two representations:
- HTML at
/passport/<cert-id>: the human-readable page - JSON-LD at
/passport/<cert-id>.json: the machine-readable document withContent-Type: application/ld+json
The JSON-LD document uses the MetrologicalCertificatePassport
type under the https://www.oimlsmart.org/cnml/passport/v1 context.
SMART instrument twins and market-surveillance aggregators consume
the JSON-LD representation.
Generating a QR code
The web app provides a QR code generator at /qr-code. It encodes
the passport URL for a specific instance certificate and renders the
QR as an SVG that can be printed on the device body.
import QRCode from "qrcode";
const passportUrl = `https://www.oimlsmart.org/cnml/passport/${certId}`;
const svg = await QRCode.toString(passportUrl, {
type: "svg",
errorCorrectionLevel: "M",
margin: 1,
width: 300,
});
import QRCode from "qrcode";
const passportUrl = `https://www.oimlsmart.org/cnml/passport/${certId}`;
const svg = await QRCode.toString(passportUrl, {
type: "svg",
errorCorrectionLevel: "M",
margin: 1,
width: 300,
});
Error correction level M (15 percent recovery) is the default. Version is auto-detected by the library based on input length.
Manufacturer instance flow
The manufacturer instance certificate flow at /issue/manufacturer-instance
combines all the pieces:
- The manufacturer enters the device identity (manufacturer, model, serial, firmware hash, manufacturing date)
- A delegated signing key is generated or loaded
- The instance cert XML is serialized via
instanceCertToXml() - The XML is signed with XMLDSig
- A QR code is generated encoding the passport URL
- The signed XML + cert PEM are bundled for download
In the SIGNATIF framework's terms, this is holder-initiated
delivery: the manufacturer collects the certificate it asked for,
and the passport is the public projection a verifier can ask for.
The framework's credential-exchange clause generalizes the pattern
into a two-turn protocol whose identifier-control challenge, proving
control of the key behind an identifier by signing a fresh nonce,
is the same construction CNML uses for device challenges. The
coordinator runs in the CA server, the holder-side client ships in
@oimlsmart/cnml-crypto (runCredentialExchange), and the web app
exposes the holder flow at /issue/collect. The current state is
recorded in the CNML profile.
Next steps
- SMI integration for the SMART instrument delivery path via the twin GraphQL interface.
- QR code delivery feature for the design rationale.