Skip to content

Publish PKIoverheid truststores (G1 + G4) on nuts.nl/certs #4603

Closed

Description

@reinkrul

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 - G1
        • QuoVadis PKIoverheid Private Services CA - G1
        • DigiCert QuoVadis PKIoverheid Private Services CA - 2023
        • Digidentity BV PKIoverheid Private Services CA - G1
    • 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 - 2025
        • DigiCert - G4 PKIo Priv G-TLS SYS - 2025
        • Digidentity - G4 PKIo Priv G-TLS SYS - 2025

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"; done

Automated 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/CODEOWNERS with 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

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions