HomeGuidesAPI Reference
Guides

Mutual TLS for API Keys

Mutual TLS (mTLS) adds a second factor to API key authentication. With mTLS enforced on a key, a request to the Ingest API must present a client certificate issued by the certificate authority (CA) registered for your workspace. A leaked API key alone is no longer enough to call the API.

You register one CA per workspace and environment. mTLS is then switched on per API key. Keys without mTLS keep working exactly as before.


1. How it works

  1. You operate a CA that issues client certificates for your integration.
  2. You register that CA certificate once in Settings → Developer → Mutual TLS. spektr adds it to the truststore of the environment's mTLS hostname.
  3. You create an API key with Require mTLS client certificate switched on, or switch it on for an existing key.
  4. Your integration calls the mTLS hostname with a client certificate issued by your CA and the API key.
  5. spektr verifies the certificate chain at the edge, then checks that the certificate's issuer is your registered CA. Either check failing rejects the request.

Once mTLS is enforced on a key, it can only be used through the mTLS hostname with a certificate from your CA. The same key sent to the regular hostname, or with a certificate from another CA, is rejected with 401 Unauthorized.


2. Hostnames

Every environment has an mTLS variant of the Ingest API hostname. It serves the same API and paths; only the transport requirements differ.

EnvironmentStandard hostnamemTLS hostname
Liveingest.spektr.commtls-ingest.spektr.com
Sandboxsandbox-ingest.spektr.comsandbox-mtls-ingest.spektr.com
Testtest-ingest.spektr.comtest-mtls-ingest.spektr.com

The mTLS hostname refuses the TLS handshake if no client certificate is presented or if the certificate does not chain to a CA in the truststore. Requests that fail here never reach spektr's application layer, so you will see a TLS error from your HTTP client rather than an HTTP status code.

Truststores and API keys are per environment, as described in Environments. Register your CA and switch on mTLS separately in each environment you use. You may use the same CA in all of them.


3. Prerequisites

Your certificate authority

  • Use a dedicated CA (or intermediate) for your spektr integration. Do not register a public CA: anyone with a certificate from that CA could reach your mTLS hostname.
  • The registered certificate must be the direct issuer of your client certificates. If you use an intermediate CA, register the intermediate.
  • The certificate must be marked as a CA (basicConstraints: CA:TRUE). Leaf certificates are refused.
  • Give the CA a distinctive subject, for example CN=Acme spektr Integration CA,O=Acme Corp,C=US. Two workspaces cannot register CAs with the same subject.
  • Use RSA 2048-bit or larger, or ECDSA P-256 / P-384. The CA must not be expired.
  • Paste the CA certificate on its own: exactly one PEM block. Bundles and chains are rejected.

Example with OpenSSL:

openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes \
  -keyout integration-ca.key -out integration-ca.crt -days 3650 \
  -subj "/CN=Acme spektr Integration CA/O=Acme Corp/C=US" \
  -addext "basicConstraints=critical,CA:TRUE" \
  -addext "keyUsage=critical,keyCertSign,cRLSign"

Your client certificates

Issue as many client certificates from the registered CA as you need. The subject is free; spektr only checks the issuer.

openssl req -new -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes \
  -keyout spektr-client.key -out spektr-client.csr \
  -subj "/CN=spektr-integration/O=Acme Corp/C=US"

openssl x509 -req -in spektr-client.csr \
  -CA integration-ca.crt -CAkey integration-ca.key -CAcreateserial \
  -out spektr-client.crt -days 365 -sha256

4. Register your CA

In Settings → Developer → Mutual TLS, paste the PEM encoded CA certificate and click Register CA. The page then shows the registered CA's subject, serial number, SHA-256 fingerprint and validity. Only the public certificate is read and stored; never paste a private key.

The truststore update can take a few minutes to reach the mTLS hostname. Use /v1/mtls-check (section 6) to confirm.


5. Switch mTLS on for an API key

API keys are managed in Settings → Developer → API keys. When generating a key, turn on Require mTLS client certificate. The switch is disabled until a CA is registered. The keys table shows Enforced for every key that requires mTLS, and the pencil icon on a row toggles it for an existing key.


6. Call the API

Send every request for an enforced key to the mTLS hostname with a client certificate from your CA. The API key header is unchanged.

curl https://mtls-ingest.spektr.com/v1/fields \
  --cert spektr-client.crt --key spektr-client.key \
  -H "x-api-key: <your api key>"

Any HTTP client works the same way. Configure it with three things:

SettingValue
Client certificatespektr-client.crt (PEM), issued by your registered CA
Client private keyspektr-client.key (PEM)
Request headerx-api-key: <your api key>

Send the request to the mTLS hostname for your environment (section 2). No other headers, paths or payloads change.

Some clients, keystores and tools expect the certificate and key as a single PKCS#12 file (.p12 / .pfx) instead of two PEM files. Create one with:

openssl pkcs12 -export -inkey spektr-client.key -in spektr-client.crt \
  -out spektr-client.p12

OpenSSL prompts for an export password, which the client then needs to open the file.

To see which certificate identity spektr observed, call the check endpoint over the mTLS hostname with any key of the workspace:

curl https://mtls-ingest.spektr.com/v1/mtls-check \
  --cert spektr-client.crt --key spektr-client.key \
  -H "x-api-key: <your api key>"
{
  "clientCertificatePresented": true,
  "issuerDN": "CN=Acme spektr Integration CA,O=Acme Corp,C=US",
  "subjectDN": "CN=spektr-integration,O=Acme Corp,C=US",
  "serialNumber": "4f2c1a9b3d7e5081"
}

Expected outcomes:

RequestResult
mTLS hostname, certificate from your CA, enforced keyNormal response
mTLS hostname, certificate from an unregistered CATLS handshake failure
mTLS hostname, certificate from another workspace's CA401 Unauthorized
Standard hostname, enforced key401 Unauthorized
mTLS hostname, certificate from your CA, key without mTLSNormal response

A 401 for an enforced key carries no detail in the body. Use /v1/mtls-check to see what identity spektr received.


7. Rotate or remove the CA

Client certificate renewals need no change in spektr as long as they are issued by the registered CA.

To rotate the CA itself, register the new CA certificate the same way as the first one. Registering replaces the previous CA: every key that enforces mTLS switches to the new CA at once, and the old CA is removed from the truststore. Plan the switch so your integration presents certificates from the new CA when you register it.

To stop using mTLS in an environment, switch it off on every key first, then click Remove CA or call DELETE /user/v1/api-keys/client-ca. Removal is refused with 400 while any key still requires mTLS.

CA expiry

spektr records the CA's validity period and shows it in Settings → Developer → Mutual TLS (validTo in the API response), but it does not yet alert you before the CA expires. Once the CA is past validTo, the mTLS hostname refuses the handshake for every certificate it issued and all enforced keys stop working. Track the expiry date on your side and rotate the CA ahead of it, following the steps above. Expiry notifications from spektr are planned.


8. Troubleshooting

SymptomLikely cause
TLS handshake error, no HTTP responseNo client certificate sent, its CA is not registered in this environment, or the truststore has not refreshed yet.
401 on the mTLS hostname with an enforced keyThe certificate was not issued by the registered CA. Compare issuerDN from /v1/mtls-check with the CA subject shown in settings.
401 on the standard hostnameThe key requires mTLS. Use the mTLS hostname.
403 Forbidden before any TLS or application errorMissing or invalid x-api-key header.
Works in Test but not LiveCA registration and API keys are per environment.
400 when switching mTLS onNo CA registered in this environment. See section 4.
409 when registering the CAThe CA subject is already taken by another workspace. Re-issue the CA with a distinctive name.

Did this page help you?