Upload Client CA

POST /v1/client-cas

Add a trusted root CA used to validate incoming client certificates on mTLS-enabled endpoints. Once uploaded, attach the CA to one or more endpoints via PUT /v1/endpoints/{id}/mtls.

The platform parses the PEM, verifies it's actually a CA cert (basicConstraints CA:TRUE), extracts subject/issuer/fingerprint metadata, and stores the original PEM bytes for chain validation at TLS-handshake time. Exactly one certificate per upload — bundles (more than one CERTIFICATE block) are rejected; split them and upload each CA separately.

Each account can have at most one CA per fingerprint. Uploading the same CA again returns 409. Plan-gated: requires the mtls_attachment entitlement on your plan.

Request body

name string Req
Friendly label. Required, max 128 chars. Shown in the dashboard's mTLS config dropdown.
description string
Optional longer description. Max 512 chars.
ca_pem string Req
PEM-encoded CA certificate. Must include -----BEGIN CERTIFICATE----- headers and parse as a valid X.509 cert with basicConstraints: CA:TRUE.

Response (201 Created)

id int64
Numeric ID. Pass to mTLS config.
fingerprint string
SHA-256 fingerprint of the CA cert. Used for deduplication.
subject_cn string
Subject Common Name extracted from the cert.
not_after datetime
CA expiry — useful to verify before saving.

Errors

400 Bad Request
Missing name, name > 128 chars, description > 512 chars, malformed PEM, more than one certificate in the PEM (bundles rejected), or cert isn't a CA.
401 Unauthorized
Missing auth.
403 Forbidden
Caller lacks the cert:write permission, or the plan doesn't include the mtls_attachment entitlement.
409 Conflict
A CA with the same fingerprint already exists on your account. Use the existing one or rotate to a new CA.
Request
curl -X POST "https://api.ngris.com/v1/client-cas" \ -H "X-API-KEY: <your_api_key>" \ -H "Content-Type: application/json" \ -d "$(jq -n \ --arg name "internal-corp-ca" \ --arg pem "$(cat root-ca.pem)" \ '{name: $name, ca_pem: $pem}')"
Python
from ngris import Ngris client = Ngris(api_key="<your_api_key>") with open("root-ca.pem") as f: pem = f.read() ca = client.client_cas.create({ "name": "internal-corp-ca", "description": "Acme Corp internal PKI root", "ca_pem": pem, }) print(f"CA #{ca['id']}, fingerprint {ca['fingerprint']}")
Response — 201 Created
{ "id": 7, "fingerprint": "ab:cd:ef:01:23:...", "subject_cn": "Acme Corp Root CA", "not_after": "2034-01-01T00:00:00Z" }
On this page
Upload Client CA
Iris