CSR Workflows

The X.509 Certificate Service creates PKCS#10 Certificate Signing Requests (CSRs) and issues certificates from them. A CSR is signed by the subject key, proving control of the private key, so CSR-based issuance gives you a proof-of-possession workflow: the requester keeps the private key and only the CSR is submitted for signing.

Service reference: Swagger API Reference

Shared Path Parameters

  • orgID: When performing operations within an organization, use the organization's Base URL or another valid host alias. For example, if your organization is named test, your default Base URL is test.enterprise-sandbox.waltid.dev on the sandbox environment.
  • target: The X.509 Certificate service path ({organizationID}.{tenantID}.{x509ServiceID}), for example test.tenant1.x509-service-1.

Create a CSR

The CSR endpoint is stateless — nothing is persisted. Store the returned csrPEM for later use.

CURL

Endpoint: POST /v1/{target}/x509-service-api/csrs | API Reference

Example Request

curl -X 'POST' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/x509-service-api/csrs' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d '{
  "subjectKeyRef": "test.tenant1.kms1.leaf-key",
  "subjectDn": "CN=Example Leaf,O=Example Org,C=US",
  "subjectAlternativeNames": [
    { "type": "dnsName", "name": "leaf.example.com" }
  ]
}'

Body Parameters

  • subjectKeyRef: String - KMS key path for the subject key, e.g. test.tenant1.kms1.leaf-key. Supply this or subjectKeyJwk, not both.
  • subjectKeyJwk: Object - Subject key as a JWK (private material), used instead of subjectKeyRef.
  • subjectDn: String (required) - Subject distinguished name, e.g. CN=Example Leaf,O=Example Org,C=US.
  • subjectAlternativeNames: Array (optional) - SAN entries, each { "type": ..., "name": ... } with type one of dnsName, email, uri, ipAddress.
  • signatureAlgorithm: String (optional) - Signature algorithm for the CSR. Defaults to an algorithm derived from the subject key.

Example Response

{
  "csrPEM": "-----BEGIN CERTIFICATE REQUEST-----
MIIB...
-----END CERTIFICATE REQUEST-----",
  "csrData": {
    "subjectName": {
      "commonName": "Example Leaf",
      "country": "US",
      "organizationName": "Example Org"
    },
    "subjectAlternativeNames": {
      "dnsNames": ["leaf.example.com"]
    },
    "publicKeyJwk": {
      "kty": "EC",
      "crv": "P-256",
      "x": "q0xi21uudhkC1QMykfYryN9bcDx480iJLSaRI05CWgY",
      "y": "NhD-09xqrUgE2-qSt8g5imePgKPPNVpYoHmsTL2f4io"
    }
  }
}

Response Fields

  • csrPEM: String - The PKCS#10 CSR in PEM format. All parsed data is derived from this value.
  • csrData: Object - Convenience view of the CSR contents (subjectName, subjectAlternativeNames, publicKeyJwk). Deprecated — it may be removed in a future version; read the values from csrPEM instead.

Response Codes

  • 200 - CSR created successfully.
  • 400 - Invalid request (e.g. no subject key, both key inputs supplied).
  • 401 - Invalid or missing authentication token.

For an ISO Document Signer CSR, supply the Document Signer's subjectDn with the ISO fields you need (CN=, C=, O=, ST=, L=). The Document Signer profile extensions are added when you later issue the certificate with certificateProfile: "iso-document-signer", not at CSR creation.

Issue a certificate from a CSR

Pass the CSR PEM as csrPem on POST /v1/{target}/x509-service-api/certificates. The subject DN and subject alternative names come from the CSR and its signature is verified before the certificate is issued. CSR-based issuance always needs an issuer — it cannot be self-signed.

CURL

Endpoint: POST /v1/{target}/x509-service-api/certificates | API Reference

Example Request

curl -X 'POST' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/x509-service-api/certificates' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d '{
  "issuerCertificateRef": "test.tenant1.x509-store-1.example-root-ca",
  "csrPem": "-----BEGIN CERTIFICATE REQUEST-----
MIIB...
-----END CERTIFICATE REQUEST-----",
  "validFrom": "2026-09-01T00:00:00Z",
  "validTo": "2027-09-01T00:00:00Z",
  "keyUsage": ["digitalSignature"]
}'

Body Parameters

  • csrPem: String (required) - The CSR in PEM format (begins with -----BEGIN CERTIFICATE REQUEST-----). Cannot be combined with subjectDn or selfSigned.
  • issuerCertificateRef / issuerCertificatePem: String (required) - The issuing certificate. issuerKeyRef / issuerKeyJwk is also accepted to specify the signing key directly.
  • subjectKeyRef: String (optional) - When set, the service checks the referenced key matches the CSR public key and records it in subjectKeyRef metadata.
  • validFrom / validTo: String (required) - Validity window.
  • Other fields are the same as certificate issuance. To apply a certificate profile — e.g. iso-document-signer against an IACA, or etsi-wrpac / etsi-wrprc against a national provider — add certificateProfile and the profile's other required fields (e.g. certificatePolicyOids) alongside csrPem.

Response Codes

  • 200 / 201 - Certificate issued (persisted when a store is attached).
  • 400 - CSR signature validation failed, subject key mismatch, or issuer not resolvable.
  • 401 - Invalid or missing authentication token.

End-to-end CSR workflow

# Step 1: Create a CSR from a key hosted in the linked KMS
CSR_RESPONSE=$(curl -s -X 'POST' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/x509-service-api/csrs' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d '{
  "subjectKeyRef": "test.tenant1.kms1.leaf-key",
  "subjectDn": "CN=Example Leaf,O=Example Org,C=US"
}')

CSR_PEM=$(echo "$CSR_RESPONSE" | jq -r '.csrPEM')

# Step 2: Issue a CA-signed certificate from the CSR
curl -X 'POST' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/x509-service-api/certificates' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d "{
  \"issuerCertificateRef\": \"test.tenant1.x509-store-1.example-root-ca\",
  \"csrPem\": $(echo "$CSR_PEM" | jq -Rs .),
  \"validFrom\": \"2026-09-01T00:00:00Z\",
  \"validTo\": \"2027-09-01T00:00:00Z\",
  \"keyUsage\": [\"digitalSignature\"]
}"

Use cases

External CA integration

Generate CSRs through the X.509 Certificate Service and submit them to an external Certificate Authority. The CSR proves possession of the private key held in your KMS.

Delegated key management

Let an external party generate its own key pair and submit a CSR. The service issues a certificate for the CSR's public key while the private key never leaves the requester.

Compliance workflows

Where a compliance framework requires proof-of-possession during issuance, CSR-based issuance satisfies it: the requester signs the CSR with the private key and the service verifies that signature before issuing.

Last updated on September 28, 2026