CSR Workflows

The X.509 Certificate Service supports PKCS#10 Certificate Signing Request (CSR) creation and CSR-based certificate issuance. This enables proof-of-possession workflows where the certificate requester proves control of the private key.

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 will be test.enterprise-sandbox.waltid.dev when using the sandbox environment.
  • target: The full X.509 Certificate service path ({organizationID}.{tenantID}.{x509ServiceID}), for example test.tenant1.x509-service-1.

Create a CSR

Create a PKCS#10 Certificate Signing Request. The CSR is signed by the subject key, proving possession of the private key. The returned CSR PEM can be submitted to an external CA or used as a subject public key source when creating certificates through this service.

Generic CSR
ISO Document Signer CSR
CURL

Endpoint: /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 '{
  "type": "generic",
  "subjectKeyDescriptor": {
    "type": "kms-hosted-key-descriptor",
    "keyIdPath": "test.tenant1.kms1.leaf-secp256r1"
  },
  "subjectName": {
    "commonName": "Example Leaf",
    "country": "US",
    "organizationName": "Example Org"
  },
  "subjectAlternativeNames": {
    "dnsNames": ["leaf.example.com"]
  }
}'

Body Parameters

  • type: String - Set to "generic" for generic CSR.
  • subjectKeyDescriptor: Object - Key descriptor for the subject key.
    • type: String - Descriptor type. Use "kms-hosted-key-descriptor" for keys stored in a KMS service or "jwk-encoded-key-descriptor" for directly provided JWK keys.
    • keyIdPath: String - (For KMS-hosted keys) The full key path in format {organizationID}.{tenantID}.{kmsServiceID}.{keyID}, e.g. test.tenant1.kms1.leaf-secp256r1.
  • subjectName: Object - Distinguished name fields (commonName, country, organizationName, stateOrProvinceName, localityName, organizationalUnitName).
  • subjectAlternativeNames: Object (optional) - SAN values (dnsNames, uris, emails, ipAddresses).

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 Codes

  • 200 - CSR created successfully.

The CSR endpoint is stateless. The service does not persist CSR state. Store the returned csrPEM for later use when creating certificates.

Issue a certificate from a CSR

Both generic certificates and Document Signer certificates can be issued using a CSR as the subject public key source. This workflow verifies proof-of-possession before issuing the certificate.

Generic certificate from CSR

CURL

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

curl -X 'POST' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/x509-service-api/certificate' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d '{
  "storedCertificateId": "generic-leaf-from-csr",
  "certificateData": {
    "subjectName": {
      "commonName": "Example Leaf From CSR",
      "country": "US"
    },
    "keyUsage": ["DigitalSignature"]
  },
  "subjectPublicKeySource": {
    "type": "csr",
    "csrPEM": "-----BEGIN CERTIFICATE REQUEST-----
MIIB...
-----END CERTIFICATE REQUEST-----"
  },
  "issuer": {
    "type": "ca-signed",
    "issuerKeyDescriptor": {
      "type": "kms-hosted-key-descriptor",
      "keyIdPath": "test.tenant1.kms1.iaca-secp256r1"
    }
  }
}'

Body Parameters

  • subjectPublicKeySource: Object - Source of the subject's public key.
    • type: String - Set to "csr" for CSR-based issuance.
    • csrPEM: String - The CSR in PEM format (begins with -----BEGIN CERTIFICATE REQUEST-----).
  • issuer: Object - Issuer configuration. Must be ca-signed for CSR-based issuance. Self-signed certificates cannot use CSR input.
    • type: String - Set to "ca-signed".
    • issuerKeyDescriptor: Object - Key descriptor for the CA signing key.
      • type: String - Descriptor type. Use "kms-hosted-key-descriptor" for keys stored in a KMS service or "jwk-encoded-key-descriptor" for directly provided JWK keys.
      • keyIdPath: String - (For KMS-hosted keys) The full key path in format {organizationID}.{tenantID}.{kmsServiceID}.{keyID}, e.g. test.tenant1.kms1.iaca-secp256r1.
  • Other parameters are the same as generic certificate creation.

Response Codes

  • 200 - Certificate issued successfully.

Document Signer certificate from CSR

CURL

Endpoint: /v1/{target}/x509-service-api/iso/document-signers | API Reference

curl -X 'POST' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/x509-service-api/iso/document-signers' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d '{
  "storedCertificateId": "ds-from-csr-2026-01",
  "iacaSigner": {
    "type": "iaca-cert-data-descriptor",
    "iacaKeyDesc": {
      "type": "kms-hosted-key-descriptor",
      "keyIdPath": "test.tenant1.kms1.iaca-secp256r1"
    },
    "certificateData": {
      "country": "US",
      "commonName": "Example IACA",
      "notBefore": "2025-05-28T12:23:01Z",
      "notAfter": "2040-05-24T12:23:01Z",
      "issuerAlternativeNameConf": {
        "uri": "https://iaca.example.com"
      }
    }
  },
  "certificateData": {
    "country": "US",
    "commonName": "Example DS",
    "crlDistributionPointUri": "https://crl-example.com"
  },
  "dsPublicKeySource": {
    "type": "csr",
    "csrPEM": "-----BEGIN CERTIFICATE REQUEST-----
MIIB...
-----END CERTIFICATE REQUEST-----"
  }
}'

Body Parameters

  • dsPublicKeySource: Set type to csr and provide the csrPEM string. This replaces the legacy dsKeyDescriptor field.
  • Other parameters are the same as Document Signer certificate creation.

    The dsKeyDescriptor field is still supported for backward compatibility, but dsPublicKeySource is preferred for new integrations. The two fields are mutually exclusive.

Response Codes

  • 200 - Document Signer certificate issued successfully.

End-to-end CSR workflow example

This example demonstrates a complete CSR-based issuance workflow:

  1. Create a CSR using a key hosted in the KMS
  2. Submit the CSR to create a CA-signed certificate
# Step 1: Create a CSR
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 '{
  "type": "generic",
  "subjectKeyDescriptor": {
    "type": "kms-hosted-key-descriptor",
    "keyIdPath": "test.tenant1.kms1.leaf-secp256r1"
  },
  "subjectName": {
    "commonName": "Example Leaf",
    "country": "US"
  }
}')

# Extract the CSR PEM (requires jq)
CSR_PEM=$(echo "$CSR_RESPONSE" | jq -r '.csrPEM')

# Step 2: Create a certificate from the CSR
curl -X 'POST' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/x509-service-api/certificate' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d "{
  \"certificateData\": {
    \"subjectName\": {
      \"commonName\": \"Example Leaf\",
      \"country\": \"US\"
    },
    \"keyUsage\": [\"DigitalSignature\"]
  },
  \"subjectPublicKeySource\": {
    \"type\": \"csr\",
    \"csrPEM\": $(echo "$CSR_PEM" | jq -Rs .)
  },
  \"issuer\": {
    \"type\": \"ca-signed\",
    \"issuerKeyDescriptor\": {
      \"type\": \"kms-hosted-key-descriptor\",
      \"keyIdPath\": \"test.tenant1.kms1.ca-secp256r1\"
    }
  }
}"

Use cases

External CA integration

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

Delegated key management

Allow external parties to generate their own key pairs and submit CSRs. The X.509 Certificate Service can then issue certificates using the CSR's public key while the private key remains with the requester.

Compliance workflows

Some compliance frameworks require proof-of-possession during certificate issuance. CSR-based workflows satisfy this requirement by having the certificate requester sign the CSR with their private key.

Last updated on June 11, 2026