Repository navigation
Publish PKIoverheid truststores (G1 + G4) on nuts.nl/certs #4603
Description
Parent: #4355. The definitions READMEs (e.g. toepassing-zorginzage-ha-vvt#52) already link to https://nuts.nl/certs.
What to publish
A landing page at https://nuts.nl/certs with:
- The PEM bundle:
https://nuts.nl/certs/production/truststore.pem - Per certificate in the bundle: subject, the official download URL it was taken from, and its SHA-256 thumbprint. No checksum of the bundle file itself: the bundle is verified certificate by certificate against these thumbprints and against the publisher.
- Which bundle for which Nuts network:
- production network and test network (acceptatie): the production bundle. Both use PKIoverheid Private Services certificates.
- stable (non-production) network: not PKIoverheid. It trusts the Nuts development CA; the page links to https://github.com/nuts-foundation/nuts-development-network-ca for that truststore. Decided not to copy that root here: it has no production trust, it has already been regenerated once (G2), and a copy would go stale.
- The CIBG TEST/ACCEPTATIE hierarchies are not used on any Nuts network and are not published.
- Where the bundle goes: the node's
tls.truststorefile(only relevant when the gRPC network / did:nuts is active) and the reverse proxy's client-certificate trust for the gRPC and FHIR endpoints. Not needed for did:x509 itself.
Bundle contents
- production (source: https://cert.pkioverheid.nl/)
- G1 (valid until 12/13-11-2028)
- Root:
Staat der Nederlanden Private Root CA - G1 - Intermediate:
Staat der Nederlanden Private Services CA - G1 - TSP CAs:
UZI-register Private Server CA G1(CIBG)KPN PKIoverheid Private Services CA - G1QuoVadis PKIoverheid Private Services CA - G1DigiCert QuoVadis PKIoverheid Private Services CA - 2023Digidentity BV PKIoverheid Private Services CA - G1
- Root:
- G4 (valid until 18/20-05-2039)
- Root:
Staat der Nederlanden - G4 Root Priv G-TLS - 2024 - Intermediate:
Staat der Nederlanden - G4 Intm Priv G-TLS SYS - 2024 - TSP CAs:
UZI Server - G4 PKIo Priv G-TLS SYS - 2025(CIBG)KPN - G4 PKIo Priv G-TLS SYS - 2025DigiCert - G4 PKIo Priv G-TLS SYS - 2025Digidentity - G4 PKIo Priv G-TLS SYS - 2025
- Root:
- G1 (valid until 12/13-11-2028)
Decided: the production bundle contains all PKIoverheid Private Services roots and intermediate CAs, not only CIBG's (except ZOVAR, see the notes under the thumbprint table). Exception: the ZOVAR Server CAs (certificates for health insurers) are left out, as there are no insurers in the Nuts ecosystem. The TLS trust in Nuts spec v1 and v2 is "PKIoverheid Private Services", whichever TSP issued the certificate; only the did:x509 pins in the definitions are UZI-specific, and those are unaffected by the bundle.
The revoked UZI Server - G4 PKIo Priv G-TLS SYS - 2024 must not be included.
Responsibility
The bundle is a convenience. Vendors remain responsible for the contents of their own truststore. The page must state this and give the verification steps below, so a vendor can check the bundle against the publishers (Logius, CIBG) before installing it, and re-check after every update.
Verification instructions (to publish with the bundle)
Download the two roots from the publisher and compare their thumbprints with the table (the G4 root also with https://www.uziregister.nl/softwareleveranciers/ca-certificaten-g4). Then verify that every certificate in the bundle chains to those roots. Only the holder of a root's private key can create a certificate that chains to it, so this covers the whole bundle.
for r in PrivateRootCA-G1 StaatderNederlandenG4RootPrivGTLS2024; do
curl -sSf "https://cert.pkioverheid.nl/$r.cer" -o "$r.cer"
openssl x509 -inform DER -in "$r.cer" -noout -subject -fingerprint -sha256
openssl x509 -inform DER -in "$r.cer" >> roots.pem
done
awk '/BEGIN CERT/{f=sprintf("bundle-%02d.pem",++n)} f{print > f} /END CERT/{f=""}' truststore.pem
for f in bundle-*.pem; do openssl verify -CAfile roots.pem -untrusted truststore.pem "$f"; doneAutomated check
scripts/verify-truststore.sh in nuts-webpresence runs on PRs and pushes touching the bundle, and weekly. Per certificate: equal to the publisher's copy (its # Source: URL), not expiring within 90 days, chains to a root in the bundle, not on its issuer's CRL. A failing scheduled run signals a revoked or expiring CA.
Governance
Changes to the truststore files require review by @stevenvegt and @reinkrul. In nuts-webpresence (no CODEOWNERS yet):
.github/CODEOWNERSwith the path of the bundles and the page, e.g./certs/** @stevenvegt @reinkrul- Branch protection on
master: "Require a pull request before merging" with "Require review from Code Owners", so no change to that path merges without one of them approving. Pushing directly must stay disabled for that branch.
Checklist
- Build the bundle; record per certificate the source URL and SHA-256 thumbprint, verified against the publisher
- Landing page with bundle, contents table, responsibility statement, verification instructions, where-to-install (nuts-webpresence)
- CODEOWNERS for the truststore path and branch protection requiring code-owner review (nuts-webpresence)
- Sources: https://cert.pkioverheid.nl/, https://www.uziregister.nl/softwareleveranciers/ca-certificaten-g4
- Announce with the use-case migration (Share migration path with relevant community member groups #4592)
Thumbprints (SHA-256 of the DER certificate, verified against the publisher)
All certificates downloaded from the source URL below and checked: every certificate chains to a root within the bundle, and the G4 root matches CIBG's published thumbprint on https://www.uziregister.nl/softwareleveranciers/ca-certificaten-g4.
| Bundle | Hierarchy | Certificate | Source | SHA-256 |
|---|---|---|---|---|
| production | G1 | Staat der Nederlanden Private Root CA - G1 | https://cert.pkioverheid.nl/PrivateRootCA-G1.cer | 0257ce27b52408e24ee2c0945640b723c5bc66ddbda4ada58c60357604f0e675 |
| production | G1 | Staat der Nederlanden Private Services CA - G1 | https://cert.pkioverheid.nl/DomPrivateServicesCA-G1.cer | 2eaaf678e645dc26ea82c016ef3960935659cf81b4c44d9b2d0fb1a142666c98 |
| production | G1 | DigiCert QuoVadis PKIoverheid Private Services CA - 2023 | https://cert.pkioverheid.nl/DigiCertQuoVadisPKIoverheidPrivateServicesCA2023.cer | b63a82ce98e9fe704dc42b7cb4b63d4bf0646b1d0754f9a4c696a4afb39436bc |
| production | G1 | Digidentity BV PKIoverheid Private Services CA - G1 | https://cert.pkioverheid.nl/Digidentity_BV_PKIoverheid_Private_Services_CA-G1.cer | bfe8f634772b0ec2cd2a41a17fc7612577d7e24f934073dec89a991b6169687e |
| production | G1 | KPN PKIoverheid Private Services CA - G1 | https://cert.pkioverheid.nl/KPN_PKIoverheid_Private_Services_CA-G1.cer | bdb68500aaae2563c57b4525784360436d3e3fd8df974b25a77f132cecc2a49d |
| production | G1 | QuoVadis PKIoverheid Private Services CA - G1 | https://cert.pkioverheid.nl/QuoVadis_PKIoverheid_Private_Services_CA-G1.cer | 69df8d18c54503f83dc239c3dcf8115b2a447efc5defca6119d18e988c12276d |
| production | G1 | UZI-register Private Server CA G1 | https://cert.pkioverheid.nl/UZI-register_Private_Server_CA_G1.cer | bdd860ef8e87e2b2c7ebb34dd6e9e1771a3a3c5dec850ba7080e3e2904dbd897 |
| production | G4 | Staat der Nederlanden - G4 Root Priv G-TLS - 2024 | https://cert.pkioverheid.nl/StaatderNederlandenG4RootPrivGTLS2024.cer | 4411f67d3d7f4f49d34ff8862249de0d6692adc92df0855fb1dd67a169800484 |
| production | G4 | Staat der Nederlanden - G4 Intm Priv G-TLS SYS - 2024 | https://cert.pkioverheid.nl/StaatderNederlandenG4IntmPrivGTLSSYS2024.cer | a24f6f2fa192dd96ceeaf8d4c380d8663426f95858956a5adff5cfd36b30554f |
| production | G4 | DigiCert - G4 PKIo Priv G-TLS SYS - 2025 | https://cert.pkioverheid.nl/DigiCertG4PKIoPrivGTLSSYS2025.cer | a3234374ce91c000c929c66daade6c85457d61850e6fb388e349fd710a9bb305 |
| production | G4 | Digidentity - G4 PKIo Priv G-TLS SYS - 2025 | https://cert.pkioverheid.nl/DigidentityG4PKIoPrivGTLSSYS2025.cer | fc6b0573c096991e59e886e28e314dfd74d96a8ea3976e197f23c2e5c49acd87 |
| production | G4 | KPN - G4 PKIo Priv G-TLS SYS - 2025 | https://cert.pkioverheid.nl/KPNG4PKIoPrivGTLSSYS2025.cer | 2b4ee93832a4b2ca349e86c21caf8f959b106c2d0aa6fd49a983fca00574d1a6 |
| production | G4 | UZI Server - G4 PKIo Priv G-TLS SYS - 2025 | https://cert.pkioverheid.nl/UZIServerG4PKIoPrivGTLSSYS2025.cer | b034cbfffcafe784edaef49fefad354edbc7823d8d6522d3da6f8e91ff28aa42 |
Notes:
- The ZOVAR CAs (
ZOVAR Private Server CA G1,ZOVAR Server - G4 PKIo Priv G-TLS SYS - 2025) are not included, to keep the bundle small: there are no health insurers in the ecosystem yet. This is not a security measure. ZOVAR falls under the same PKIoverheid regime, and a peer that presents its full chain validates against the same roots anyway. - The revoked 2024 G4 TSP CAs (UZI Server, ZOVAR Server, Digidentity) are excluded.
Status
Bundle, landing page, CODEOWNERS and the automated check: nuts-foundation/nuts-webpresence#430 (merged 2026-10-10). Follow-up: nuts-foundation/nuts-webpresence#435 makes the bundle link on the page a download, because GitHub Pages serves .pem as application/x-x509-ca-cert and some browsers otherwise offer to import it as a CA. Branch protection on master now has "Require review from Code Owners" enabled (2026-10-02); it takes effect for /public/certs/** and the page once the PR with .github/CODEOWNERS is merged. "Do not allow bypassing the above settings" is enabled too (2026-10-06), so admins cannot push to master directly or merge without the required reviews.
Metadata
Metadata
Assignees
Labels
Type
Fields
Priority
Activity
Publish PKIoverheid truststores on /certs (#430)