Get an X509Credential from a UZI certificate

Many use cases identify care organizations by their URA number. The CIBG doesn't issue Verifiable Credentials with the URA yet, so you create one yourself from the care organization's UZI server certificate: an X509Credential.

The node uses the X509Credential to:

The X509Credential is:

It contains the UZI certificate, and the URA, name and city taken from it. It does not contain the private key.

For background, such as how the URA ends up in the credential and which certificate authority a use case trusts, see X509Credential with UZI server certificates.

Do this once per care organization, per environment.

Who does what

The UZI certificate and its private key belong to the care organization. Ideally, the private key never leaves the care organization:

Step Who
Create the subject and give its did:web DID to the care organization Vendor
Create the X509Credential with the UZI certificate and private key Care organization
Send the X509Credential (a JWT, without the private key) to the vendor Care organization
Load the X509Credential into the wallet Vendor

In practice, the vendor often already manages the care organization's UZI certificate, e.g. for client TLS connections. The vendor then has the private key anyway, and can create the X509Credential itself. The steps below work for the care organization and the vendor alike.

Before you start

Create the credential

Put the certificate chain (certificate.pem) and private key (privatekey.pem) in a directory called certs. From the directory that contains certs, run:

docker run --rm -v "$(pwd)/certs:/certs" \
  nutsfoundation/go-didx509-toolkit:1.2.0 \
  vc /certs/certificate.pem /certs/privatekey.pem \
  "<CA name>" \
  <did>

Check https://hub.docker.com/r/nutsfoundation/go-didx509-toolkit/tags for the latest version.

The output is the X509Credential as a JWT (a long string starting with eyJ). Send it to the vendor, who loads it into the care organization's wallet (see "Load the credential into the wallet").

Non-production environments

For non-production environments, the CIBG issues test certificates whose name, URA and city don't match the real care organization. Where the use case allows it, you can instead create a fake UZI server certificate with a test CA:

  1. Check out https://github.com/nuts-foundation/go-didx509-toolkit. You need Bash and openssl.

  2. In the test_ca directory, run:

    ./issue-cert.sh <domain (CN)> <name (O)> <city (L)> <uzi> <ura> <agb>
    

    The domain, UZI and AGB values can be anything; use cases don't use them.

  3. The certificate chain and private key are written to the out directory. Copy them to your certs directory.

  4. Create the credential as above, but with "CN=Fake UZI Root CA" as the CA:

    docker run --rm -v "$(pwd)/certs:/certs" \
      nutsfoundation/go-didx509-toolkit:1.2.0 \
      vc /certs/<domain>-chain.pem /certs/<domain>.key \
      "CN=Fake UZI Root CA" \
      <did>
    

Which CAs an environment accepts is set in the use case's Discovery Service definition.

360-graden-clientbeeld

The X509Credential is the only credential a care organization needs to obtain. Accepted certificates per environment:

Environment Accepted certificates
Development, test Fake UZI certificates and CIBG test certificates (G1 and acceptance G4)
Acceptance CIBG test certificates (G1 and acceptance G4) and real G1 certificates. Not fake ones, and not real G4 ones.
Production Real CIBG certificates only (G1 and G4)

Lifecycle

The X509Credential is only valid as long as the UZI certificate it was created from. Create and load a new X509Credential:

Load the new credential as described in "Load the credential into the wallet", then remove the old one (see "Renew credentials").


Revision #12
Created 2025-08-12 11:56:24 UTC by Jorrit Spee
Updated 2026-10-28 06:16:30 UTC by Rein Krul