Skip to main content

Certificates

X.509 certificates are used to bind a public key to an entity through the signature of a trusted Certificate Authority (CA). This enables wallet holders to know with whom they interact, and lets verifiers know that presented credentials are signed by trusted issuers.

Certificate identifiers are used for credential issuance and verification. Certificate Authority identifiers are used to sign and issue certificates for other entities.

Check if you can use certificates

Retrieve the configuration through the API and check two things:

  1. Whether certificates are enabled in your system. The identifier object determines the types of identifier available to you:

"identifier": {
"CERTIFICATE": {
"display": "identifier.certificate",
"enabled": true,
"order": 1
},
"CA": {
"display": "identifier.ca",
"enabled": true,
"order": 2
}
},
  1. Whether the credential format you want to work with is compatible with certificates. Formats have capabilities that specify which identifier types are compatible:

"format": {
"EXAMPLE_FORMAT": {
"capabilities": {
"issuanceIdentifierTypes": [
"DID",
"CERTIFICATE" // You can use certificates to issue credentials of this format
],
"verificationIdentifierTypes": [
"DID",
"CERTIFICATE" // You can use certificates to verify credentials of this format
],
},
"display": "format.example",
"type": "EXAMPLE_FORMAT"
}
}

Create a certificate identifier

Certificate identifiers are used for issuing and verifying credentials. The workflow involves creating ingredients within the system, obtaining a signature from a CA (either external or your own), then importing the signed certificate as an identifier.

1. Create a key pair

Generate an ECDSA or EDDSA key pair.

Related guide: Create a key pair

2. Create a CSR

CSR operations

Generate a Certificate Signing Request using your key. If you plan on issuing ISO mDL (DocType: org.iso.18013.5.1.mDL), set the profile to MDL to add the necessary extensions. Otherwise, set to GENERIC.

3. Get the CSR signed

Submit your CSR to a Certificate Authority that offers SHA256 signatures. This can be an external CA or a CA identifier you've created in the system. When your request is completed, download the signed certificate in PEM format.

4. Import the signed certificate

Identifier operations

Create a new identifier with type CERTIFICATE. Provide the certificate chain in PEM format and reference the key ID used to create the CSR. If your certificate has no common name (CN), you must provide a name during identifier creation.

Example request body:

{
"name": "My Certificate Identifier",
"organisationId": "{{ORG-UUID}}",
"certificates": [
{
"chain": "-----BEGIN CERTIFICATE-----\nMIIDo.....\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIIC6j....\n-----END CERTIFICATE-----\n",
"keyId": "{{KEY-UUID}}",
"name": "Optional certificate name"
}
]
}

The chain field must include the leaf certificate and can optionally include intermediate and root certificates up the chain. The system validates that the certificate is currently valid, that the referenced key matches the certificate's public key, and that the chain is properly signed.

5. Use the certificate identifier

Once imported, use your certificate identifier for credential operations:

  • Issuance: Reference the identifier UUID as the issuer when creating a credential
  • Verification: Reference the identifier UUID as the verifier when creating a proof request

Import a CA certificate chain

If you have a CA certificate signed by an external authority, you can import it as a CA identifier.

1. Create a key pair

Generate an ECDSA or EDDSA key pair.

Related guide: Create a key pair

2. Create a CSR

CSR operations

Generate a Certificate Signing Request using the CA profile to include appropriate CA extensions.

3. Get the CSR signed externally

Submit your CSR to an external Certificate Authority. When completed, download the full certificate chain in PEM format.

4. Import the CA chain

Identifier operations

Create a new identifier with type CA. Provide the full certificate chain where the leaf certificate is your CA certificate.

Example request body:

{
"name": "My CA Identifier",
"organisationId": "{{ORG-UUID}}",
"certificateAuthorities": [
{
"chain": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----\n",
"keyId": "{{KEY-UUID}}",
"name": "Optional CA name"
}
]
}

The system validates that the leaf certificate is a CA certificate (with CA:TRUE in basic constraints), that it's signed by the specified key, and that the chain is properly signed.

Create a self-signed root CA

To create your own root CA without external signing, you can generate a self-signed CA certificate directly.

1. Create a key pair

Generate an ECDSA or EDDSA key pair.

Related guide: Create a key pair

2. Create the self-signed CA identifier

Identifier operations

Create a new identifier with type CA and provide the certificate subject information. The system generates and self-signs the CA certificate.

Example request body:

{
"name": "My Root CA",
"organisationId": "{{ORG-UUID}}",
"certificateAuthorities": [
{
"keyId": "{{KEY-UUID}}",
"name": "Optional CA name",
"selfSigned": {
"content": {
"commonName": "Acme Root CA",
"organization": "Acme Corporation",
"country": "CH"
},
"signer": "X509_CERTIFICATE",
"validityStart": "2025-01-01T00:00:00Z",
"validityEnd": "2035-01-01T00:00:00Z"
}
}
]
}

The system creates a self-signed CA certificate with the specified subject information and validity period.

Use the CA identifier

CA identifiers can be used to:

  • Issue Access Certificates to relying parties (required by EUDI wallet specifications)
  • Sign X.509 certificates through the signature endpoint for other certificate workflows

Certificate and CA status

Identifier detail

Retrieve the identifier detail and check the state field for status: ACTIVE or DEACTIVATED. Certificates and CAs are active unless none of the certificates in the chain are currently valid.

You can run a task using the Core API with the following request body to update certificate status:

{
"name": "CERTIFICATE_CHECK"
}