Certificates
Paradym enables you to use X.509 certificates to sign OpenID4VC presentation requests, issue mDoc/SD-JWT-VC credentials, and sign credential revocation status lists.
To do so, you can either create a root certificate within Paradym for the specific use case, or create a certificate signing request to request an externally signed certificate.
When you create a root certificate within Paradym, the root certificate is used to automatically generate leaf certificates, which are used for the actual signing of credentials and OpenID4VP presentation requests. When you use an externally signed certificate, you need to first create a certificate signing request, get your certificate signed by an external certificate authority, and then import the resulting certificate into Paradym.
You can only have one active certificate for each certificate type (issuer/verifier) and key type combination at a time. This applies to both root certificates created in Paradym, as well as externally signed leaf certificates.
For example, you cannot have both an active issuer root certificate and an active externally signed issuer leaf certificate for the same key type.
However, you can have both an active and a pendingActivation certificate at the same time, which allows for pre-rotation and preparation for certificate renewal.
Creating a Root Certificate
When creating a root certificate, you need to provide the following information:
- The type of the root certificate to create. At the moment you can choose to create a verifier root certificate (which will generate a leaf certificate used for OpenID4VP presentation requests), or an issuer root certificate (which will generate a leaf certificate used for signing credentials).
- The type of the Private Key used to sign the root certificate.
- The key backend that determines where the private key material is generated and stored. The
softwarebackend generates and stores the key in software, and is the default. To see which backends your deployment offers, requestGET /v1/wallets/{walletId}/key-backends. Each one carries anidto pass askeyBackend, and thekeyTypesit can create, since not every backend can create every key type. - The ISO 3166-1 2-letter country code of the country where the issuer is located, and, optionally, a human-readable common name, identifying the certificate issuer.
- The issuer alternative name, which is the URL that identifies the issuer.
The keyBackend field is optional and defaults to software. The dashboard only offers the backends that are enabled for your deployment; through the API, selecting a backend that is not enabled results in an error. Reach out to us if you want to use a hardware-backed key backend.
By default, the root certificate has a validity of 5 years. If you need to renew it beforehand because, for example, your details have changed, you can create a new certificate, and activate it. This will automatically deactivate the old one (but not revoke it).
When a root certificate is about to expire, an email will be sent to the wallet owner to inform about the renewal. For verifier root certificates this is 6 months before expiration of the certificate. For issuer root certificates this is 6 months before the the longest validity of any of the credentials issued by this issuer root certificate. For example if you have a credential template that issues credentials that are valid for up to 1 year, the notification will be sent 1.5 years before expiration. The 6 months allows for enough time to share the new root certificate with all relevant parties.
To create a certificate from the API, make a POST request to https://api.paradym.id/v1/wallets/{walletId}/certificates. See the API Reference for detailed usage information.
{
"type": "verifierRoot",
"keyType": "P-256",
"keyBackend": "software",
"countryName": "NL",
"commonName": "Example Company BV",
"issuerAlternativeNameUrl": "https://example.com"
}Keys
Paradym tracks every key it creates, so you can see which keys exist, where they live and what is scheduled to happen to them. This covers externally signed certificates too: the key behind a signing request is generated by Paradym on the backend you selected, and tracked the same way.
Keys are listed in the dashboard under Trust -> My Keys, and through GET /v1/wallets/{walletId}/keys. Each certificate carries the keyId of the key it signs with, so you can go straight from a certificate to its key.
A key holds:
id- how you address the key in Paradym, and what a certificate’skeyIdpoints at.backendKeyId- the key’s own identifier in whichever backend holds it. Not unique across backends, so useidto address a key. Only returned on an on-premise deployment, where the backend is yours: on Paradym’s hosted platform the identifier describes our infrastructure, which you cannot reach, so it is withheld.keyBackend, where the key material lives.status:active,pendingDeletiononce its deletion has been arranged, ordeletedonce the material is gone.scheduledDeletionAt, when the material is expected to be gone, anddeletedAtonce it actually is.
What a key is used for is not returned by default, since a certificate and a signing request are resources in their own right. Request them when you need them:
GET /v1/wallets/{walletId}/keys?include=certificate,certificateSigningRequestcertificate- the certificate this key signs for.certificateSigningRequest- the signing request this key was created for. It stays listed after its signed certificate is imported, so an imported key returns both.
Filter with ?filter[status]= (active, pendingDeletion, deleted) and ?filter[keyBackend]=
(software, or the name of an externally-managed backend).
Both are returned in full, as on their own endpoints. A key is held by at most one of each: it is created with a certificate, and an imported certificate reuses its signing request’s key.
Key Lifecycle
When the certificate a key backs has reached the end of its life, the key is retired: it stops working immediately, and its material is destroyed after a grace period (30 days by default). Until the material is destroyed the retirement can be cancelled, where doing so would give you back a usable key.
A certificate reaches the end of its life when it is revoked or has expired. Deactivating a certificate is not enough, for imported certificates either: a deactivated certificate can still revoke the credentials it issued, and signing that revocation needs its key.
Some backends only schedule destruction rather than performing it immediately, so the key stays pendingDeletion until its backend has actually destroyed it. Software keys are reclaimed the same way: they cost nothing to hold, but there is no reason to keep material a wallet can never use again.
Deleting a Key
An imported certificate is never revoked by Paradym (only the issuing CA can), so deactivating it is as far as its lifecycle goes and its key would otherwise be held, and billed, until it expires. Deleting the key by hand releases it:
DELETE /v1/wallets/{walletId}/keys/{keyId}or the Delete action on the key under Trust -> My Keys in the dashboard. The key stops working immediately and its material is destroyed after the same grace period as an automatically reclaimed key.
The request is refused while anything still needs the key:
- a certificate that is
active,pendingActivationorpendingRevocation; - an
activesigning request, whose signed certificate could still be imported.
Revoke or deactivate those certificates, and import or delete those signing requests, first. The error names every record that is blocking.
Once the material is destroyed this cannot be undone, and it can cost you the ability to revoke. A deactivated certificate can still revoke what it issued, and that needs its key to sign the status list update. Only delete a key when you are sure nothing issued under its certificate will need revoking.
For a root certificate’s key the cost is wider. A certificate revocation is published on the root’s revocation list, which is signed with that key, so deleting it gives up revoking the root itself and every certificate beneath it. Paradym refuses such a revocation rather than accepting one it can never publish. The existing revocation list also stops being refreshed, so relying parties eventually fetch one that is past its own next update.
Cancelling a Deletion
While a key is pendingDeletion its material still exists, so the deletion can be undone:
POST /v1/wallets/{walletId}/keys/{keyId}/cancel-deletionor the Cancel deletion action in the dashboard. The key becomes usable again straight away. This works for the whole grace period on every backend: where the backend has already been asked to destroy the key, Paradym restores it first, so success always means the key can sign again.
It is only allowed where cancelling gives you back something usable. It is refused when every certificate the key signs for is revoked or expired, since such a key can no longer sign, have its status lists refreshed, or therefore revoke.
That is also the exact condition Paradym reclaims keys on, so a deletion you did not ask for cannot be cancelled - create a new certificate instead. Cancelling is for a key you deleted by hand, where a deactivated certificate or a pending signing request still needs it.
Creating a Certificate Signing Request
In a lot of cases the authority issuing certificates is external to your issuer or verifier solution, in which case it is not possible to directly generate a certificate that will be trusted by other parties within Paradym.
Paradym supports creating Certificate Signing Requests based on PKCS#10 if you need a certificate to be signed by an external certificate issuer. A certificate signing request can only be created for leaf certificates (the certificate that will be used directly to sign a credential or OpenID4VP presentation request). Certificate Signing Requests are automatically removed, including the associated cryptographic keys, one month after they are created if no certificate has been imported yet.
Only the signing is external: Paradym generates the key, on the key backend you choose with keyBackend, and the imported certificate reuses that same key. So an externally signed certificate is externally keyed only if its request was, and it cannot be moved to another backend afterwards.
While root certificates within Paradym are valid for 5 years, leaf certificates used for issuing credentials and signing OpenID4VP verification requests are valid for a maximum of 457 days, in line with the requirement from ISO 18013-5 mDoc specification for Document Signer Certificates.
We recommend initiating the renewal process for externally signed certificates at least 1 month before expiration of the certificate for externally signed verifier certificates.
For externally signed issuer certificates this is 1 month before the longest validity of any of the credentials issued by this issuer certificate. For example, if you have a credential template that issues credentials that are valid for up to 1 year, and the certificate is valid for 457 days (the maximum allowed within Paradym), you only have around 2 months to use the certificate before we recommend initiating the renewal process.
An email will be sent to the wallet owner to inform about the renewal. We highly recommend automating the external certificating singing process through our API if possible.
To create a certificate signing request from the API, make a POST request to https://api.paradym.id/v1/wallets/{walletId}/certificates/csrs. See the API Reference for detailed usage information.
{
"type": "verifierSignRequest",
"keyType": "P-256",
"keyBackend": "software",
"countryName": "NL",
"commonName": "Example Company BV"
}Once the certificate signing request has been created you should share the request with the certificate issuer. The signed certificate can then be imported into Paradym, see Importing an Externally Signed Certificate below.
Some certificate issuers don’t accept a PKCS#10 certificate signing request and instead ask for the raw public key. From the My Certificates section in the dashboard, open the request’s ⋯ menu and use Copy public key to copy the SPKI PEM (-----BEGIN PUBLIC KEY-----) of the request. Copy request copies the full PKCS#10 request instead.
Importing an Externally Signed Certificate
When the certificate has been signed by the certificate issuer, you can import it into Paradym through the dashboard or API.
Make sure you import the certificate for the correct certificate signing request. The imported certificate must match the certificate signing request (subject, public key, and extensions), and will be rejected otherwise.
If your certificate authority uses a multi-level PKI hierarchy (i.e. the leaf certificate is not directly signed by the root certificate), you can provide additional intermediate certificates that form a chain. The certificates should be ordered from leaf-adjacent to root-adjacent. If a root certificate is included in the list, it will be ignored.
To import a signed certificate for a certificate signing request from the API, make a POST request to https://api.paradym.id/v1/wallets/{walletId}/certificates/csrs/{certificateSigningRequestId}/import. See the API Reference for detailed usage information.
You can optionally provide the parentCertificates field to import additional intermediate certificates that will be used in credentials and requests signed with the imported certificate.
{
"certificate": "-----BEGIN CERTIFICATE-----\nMIIB0zCCAYWgAwIBAgIUcxM9poL1rQ9qE+zKG66d1Ot/sswwBQYDK2VwMD8xCzAJ\nBgNVBAYTAk5MMRgwFgYDVQQKDA9BbmltbyBTb2x1dGlvbnMxFjAUBgNVBAMMDUFu\naW1vIFJvb3QgQ0EwHhcNMjYwMTEwMTYxMzU5WhcNMjcwMTEwMTYxMzU5WjApMRow\nGAYDVQQDExFVdG9waWEgR292ZXJubWVudDELMAkGA1UEBhMCTkwwWTATBgcqhkjO\nPQIBBggqhkjOPQMBBwNCAAT9WNvzCjNN2jMErOQ8SngFl9kOYrF2vGM6wzcjOlm5\nZkmP8hAw1Mq4ufWXLrJJSt6nttLmnjp+fhFtt5PLlWg4o3oweDAdBgNVHQ4EFgQU\niYGgIscPPL8onQf7XSjGoh02JgwwDgYDVR0PAQH/BAQDAgeAMCYGA1UdEQQfMB2C\nGzJlM2FmNDdlMTA3Ni5uZ3Jvay1mcmVlLmFwcDAfBgNVHSMEGDAWgBQZnA7JLD1U\nwdTyQo+7q6q34fq6HzAFBgMrZXADQQDUvLOLNklte8eSVzpd0RsPuAZPAdF1cFc3\ngHH2IjAugRiBnCMZ/iz/wtQRymwa5nmCX/xJF+f/n+C3e3jpNtoI\n-----END CERTIFICATE-----",
"parentCertificates": [
"-----BEGIN CERTIFICATE-----\n<intermediate-certificate>\n-----END CERTIFICATE-----"
]
}Activate a Certificate
If you have a certificate of a certain certificate type and key type combination and create a new one, the new one will be “pending activation”. This means that the new certificate won’t be used until it is activated. That happens automatically when the currently active one expires.
However, you can manually activate the new one, which automatically deactivates the old one. This can be useful when you want to update information contained in the certificate, or during renewal, if you have already shared the new certificate with all relevant parties and want to start using the new one immediately.
To activate a certificate from the API, make a POST request to https://api.paradym.id/v1/wallets/{walletId}/certificates/{certificateId}/activate. See the API Reference for detailed usage information.
Revoking a Certificate
Revoking a certificate should be done if the certificate is compromised. This can be easily done via the dashboard or the API. Afterwards, the certificate will be pending revocation. Once the Certificate Revocation List has been updated, the certificate status will change to revoked.
Note that revoking a certificate is an irreversible operation. In addition, if you revoke a root certificate, we will automatically revoke all its children certificates.
A revocation is published on the root certificate’s revocation list, which is signed with the root’s key. Revoking is therefore refused once that key has been deleted, since the revocation could never be published and the certificate would sit pending revocation for good. If the key is still pendingDeletion, cancelling the deletion restores it and the revocation can go ahead. Deleting a leaf certificate’s key does not affect this: the revocation list is signed by the root.
When verifying a credential or OpenID4VP presentation request, Paradym checks the issuer’s full X.509 certificate chain against its Certificate Revocation List (CRL). If any certificate in the chain has been revoked, verification fails and the credential is rejected.
CRLs are cached for up to one hour during verification. As a result, a revocation can take up to an hour to take full effect: verifications may still succeed for up to one hour after a certificate in the chain is revoked. If a CRL is temporarily unreachable, verification is not blocked, so transient network issues won’t cause otherwise valid credentials to be rejected.
It is not possible to revoke an externally signed certificate (imported through a certificate signing request), as the revocation of certificates is handled by the certificate issuer.
If an externally managed certificate is compromised you need to contact the certificate issuer and request revocation.
To revoke a certificate from the API, make a POST request to https://api.paradym.id/v1/wallets/{walletId}/certificates/{certificateId}/revoke. See the API Reference for detailed usage information.
Presentation Templates
You can use the certificates to authenticate presentation requests. To do so, you first need to create a certificate, as described above. Then, you need to create a Presentation Template as described in the documentation. In that page, you can choose the authentication method, which, by default, will be did:web. You can also choose to use any of the available X.509 certificates.