mTLS Integration (Optional)
Set up mutual TLS authentication for RiskOS™ API calls using client certificates to enforce two-way identity verification.
What is mTLS?
mTLS (Mutual TLS) is a security protocol where both the client and server authenticate each other using certificates, unlike regular TLS where only the server is authenticated.
How it works
Socure provides a dedicated mTLS endpoint for each environment:
| Environment | mTLS base URL |
|---|---|
| Sandbox | https://mtls.riskos.sandbox.socure.com |
| Production | https://mtls.riskos.socure.com |
- Transport: HTTPS with mutual TLS (mTLS)
- Policy: Client certificate is required – connections without a valid certificate are rejected at the load balancer.
- Supported operations: All API Reference endpoints are available through the mTLS base URL.
At this endpoint:
- The External HTTPS Load Balancer:
- Terminates TLS
- Validates the client certificate against our configured trust store
- Allows only requests presenting a valid client certificate issued from the agreed-upon client CA to reach our services.
- Application authentication/authorization (for example, the Bearer token) still enforced on top of mTLS
Account-level constraints:
- Account-Level Identity: mTLS certificates are configured at the Account level, not per use case. All teams or applications within the same RiskOS™ account must use the same certificate bundle.
- Product Separation: You cannot reuse mTLS certificates from Socure ID+. Because RiskOS™ is a separate account environment, a new certificate exchange specifically for RiskOS™ is required.
- Optional Usage: mTLS is not strictly enforced for the entire account unless required by your internal policy.
- To use mTLS: Call the mTLS base URL for your environment —
https://mtls.riskos.sandbox.socure.com(Sandbox) orhttps://mtls.riskos.socure.com(Production).- To skip mTLS: Call the standard endpoint —
https://riskos.sandbox.socure.com(Sandbox) orhttps://riskos.socure.com(Production).
Flow diagram
This diagram shows the end-to-end mTLS connection — what happens at each hop between the client, the RiskOS™ load balancer, and the RiskOS™ API server. Note that the client verifies the server certificate (step 3) before it presents its own client certificate.
sequenceDiagram
title RiskOS™ mTLS — End-to-End Flow
participant C as Client
participant LB as RiskOS™ Load Balancer
participant API as RiskOS™ API Server
Note over C: Customer generates PKI chain:<br/>Root CA → Intermediate CA → Leaf client cert
Note over C,LB: Before integration: customer shares<br/>CA bundle (Root + Intermediate) with Socure
C->>LB: 1. ClientHello — TLS handshake initiated
LB->>C: 2. Server presents its certificate
C->>C: 3. Client verifies server certificate<br/>(public CA or configured trust anchor)
LB->>C: 4. Server requests client certificate
C->>LB: 5. Client sends leaf certificate
LB->>LB: 6. Validate client cert against TrustConfig<br/>(customer CA bundle)
alt Invalid or missing client cert
LB--X C: TLS handshake failure
end
Note over C,LB: 7. Encrypted TLS session established
C->>LB: 8. Encrypted HTTPS request
LB->>API: 9. Plain HTTP request<br/>(TLS terminated at load balancer)
API->>API: 10. Application auth<br/>(Bearer token / API key)
API-->>LB: 11. HTTP response
LB-->>C: 12. Encrypted HTTPS response
At each layer
| Layer | What happens |
|---|---|
| Client | Initiates the TLS handshake, verifies the RiskOS™ server certificate, presents the leaf certificate and private key when requested, sends the encrypted HTTPS request, and receives the encrypted HTTPS response. |
| RiskOS™ load balancer | Presents the server certificate, requests and validates the client certificate against TrustConfig, terminates TLS, forwards plain HTTP to the backend, and re-encrypts the response over TLS back to the client. |
| RiskOS™ API server | Enforces Bearer token authentication on top of mTLS, then processes the request and returns the response. |
Prerequisites
Make sure the following are in place:
- Ability to perform HTTPS requests with client certificate authentication.
- Required certificate assets unique to your RiskOS™ account:
- A client certificate (client.crt).
- Its private key (client.key).
- The client CA / chain that issued that certificate.
- Share your CA bundle (Root and Intermediate public certificates) with Socure for configuration in our Trust Store. See What to send Socure for the required format.
Certificate requirements
Certificate roles
Each certificate in the chain has a distinct role. Only your CA public certificates are shared with Socure; your leaf certificate and private key stay on your side.
| Certificate | Basic Constraints | Extended Key Usage | Send to Socure? | Customer uses at runtime? |
|---|---|---|---|---|
| Root CA | CA:TRUE (required) | — | Yes (public certificate only) | No |
| Intermediate CA | CA:TRUE (required) | — | Yes (public certificate only) | No |
| Leaf (client) certificate | CA:FALSE (required) | TLS Web Client Authentication (required) | Optional (for testing only) | Yes (client.crt and client.key) |
Do not send Socure a CSR:
Socure does not sign customer certificate requests. Generate and sign certificates on your side using your internal PKI, then share your CA public certificates (Root and Intermediate) for Trust Store configuration.
Note:
Socure configures CA certificates (Root and Intermediate) in our GCP Trust Store — not individual client leaf certificates. Your leaf certificate is used only on your side when calling the mTLS endpoint. Because Socure trusts the CA rather than the leaf certificate, you can issue a new leaf certificate from the same CA without a new certificate exchange.
1. Client certificate type
- Must be an X.509 v3 certificate suitable for TLS client authentication.
- Must be issued by a CA that we mutually agree on and configure in our GCP TrustConfig as a trustAnchor.
- The CA bundle must contain the chain: Intermediate CA → Root CA.
- Key size: RSA 2048+ or ECDSA (P-256).
- The chain must validate with
openssl verify.
2. Subject / DN
Use stable identifiers that describe your application, RiskOS™ integration, environment, and organization.
Recommended CN pattern:
{application}-riskos-{environment}.{your-domain}
Examples:
- Sandbox:
onboarding-riskos-sandbox.acme-finance.com - Production:
payments-riskos-prod.acme-finance.com
The riskos segment identifies the certificate for RiskOS™ mTLS integration. Replace acme-finance.com with your organization's domain.
Keep O and OU distinct:
- O (Organization): Your company's legal name — for example,
Acme Finance Corporation. - OU (Organizational Unit): The internal team that owns the integration — for example,
Enterprise API Platform.
Do not use RiskOS in O or OU — those describe your organization, not Socure's product.
Socure maps certificate identity (CN / DN / serial / issuer) to your account for future reference.
How Socure configures trust on our side
You don't need to do this, but it helps you understand the behavior:
- We configure a ServerTlsPolicy on the Target HTTPS Proxy with:
-
clientValidationMode = REJECT_INVALID→ Any missing/invalid client certificate is rejected at TLS handshake
-
clientValidationTrustConfigpointing to a TrustConfig that contains your client CA undertrustAnchors
-
Implication for you: If your client does not present a valid certificate signed by this CA, the TLS handshake fails before any HTTP request is received.
What to send Socure
Share a PEM file that contains your CA chain (public certificates only):
-----BEGIN CERTIFICATE-----
(Intermediate CA — CA:TRUE)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
(Root CA — CA:TRUE)
-----END CERTIFICATE-----
Never share private keys (
*.key), certificate signing requests (CSRs), or leaf private keys.
Allow 3–5 business days for Trust Store configuration after submission.
Client-side configuration – general
From the client side, mTLS is simply:
- "Use this certificate + key when calling
https://mtls.riskos.socure.com"
You typically configure:
- Client certificate file (PEM or PFX)
- Private key file (if not bundled)
- Trusted server CA (optional if our server certificate is from a public CA your system already trusts)
Example integrations
1. cURL
curl -v \
--cert /path/to/client.crt \
--key /path/to/client.key \
--cacert /path/to/ca_root.crt \
https://mtls.riskos.socure.com/api/evaluation
--header 'accept: application/json' \
--header 'content-type: application/json'
--data '
{
"data": {
"individual": {
.....
},
....
},
....
}import requests
url = "https://mtls.riskos.socure.com/api/evaluation"
headers = {
"accept": "application/json",
"content-type": "application/json",
}
payload = {
"data": {
"individual": {
# ...
},
# ...
},
# ...
}
response = requests.post(
url,
headers=headers,
json=payload,
cert=("/path/to/client.crt", "/path/to/client.key"),
verify="/path/to/ca_root.crt",
)
data = response.json()Notes:
--cert: Client certificate (PEM). If combined with key in PFX, use--cert client.p12:password --cert-type P12--key: Client private key--cacert: CA to verify our server certificate (optional if you already trust the issuing public CA)
If the certificate is missing or invalid, you see a TLS handshake error such as:
SSL_ERROR_HANDSHAKE_FAILURE_ALERTOPENSSL_internal:KEY_VALUES_MISMATCHSocket hang up
2. Python as a client
import requests
BASE_URL = "https://mtls.riskos.socure.com"
# Paths to your certificate files
CLIENT_CERT = "/path/to/client.crt" # client certificate (PEM)
CLIENT_KEY = "/path/to/client.key" # client private key (PEM)
CA_CERT = "/path/to/ca_root.crt" # CA to trust our server cert (optional if system trust is enough)
def main():
try:
# JSON payload matching your curl example
payload = {
"data": {
"individual": {
....
},
....
},
....
}
headers = {
"accept": "application/json",
"content-type": "application/json",
}
response = requests.post(
f"{BASE_URL}/api/evaluation",
headers=headers,
json=payload, # sends JSON body like curl --data '<json>'
cert=(CLIENT_CERT, CLIENT_KEY),
verify=CA_CERT, # same as --cacert; use True if using system trust store
timeout=10,
)
print("Status:", response.status_code)
print("Body:", response.text)
except requests.exceptions.SSLError as e:
print("TLS/mTLS error:", e)
except requests.exceptions.RequestException as e:
print("Request error:", e)
if __name__ == "__main__":
main()API behavior and authentication
Please note the following important points:
- mTLS = transport-level identity, not necessarily your full application authentication
- You must still provide a Bearer token in
Authorization: Bearer YOUR_API_KEY - Typical pattern:
- mTLS authenticates the calling system
- The Bearer token authenticates the user or client app context
Error scenarios you should expect
- TLS handshake failure (no HTTP status code)
- Likely causes:
- Missing client certificate
- Invalid chain (not signed by configured CA)
- Expired or not yet valid certificate
- Resolution:
- Check your client certificate/key configuration
- Check certificate validity dates
- Confirm you're using the correct certificate for production vs sandbox
- Confirm CA chain matches what you shared with us
- Likely causes:
- HTTP 401 / 403 / 429 from API
- mTLS succeeded, but:
- Bearer token is invalid or missing
- Your IP is not whitelisted in our system
- Your request hit the rate limit
- mTLS succeeded, but:
- HTTP 404 / 405 / 500 responses
- mTLS layer is OK; these are regular API-level errors (wrong path, method, or internal error)
Certificate rotation guidance
Customer responsibilities:
- Rotate customer certificates before the
not_afterdate - Notify us of the new customer CA (if your CA changes)
Socure will:
- Update our TrustConfig / trustAnchors if your CA changes
- Keep both old and new CAs during migration windows when needed
How to inform us: Contact our Support team at [email protected].
Lead time required: Please allow 3–5 business days for CA changes
Common error messages and causes
Errors are often reported by the client's application, browser, or server logs during the TLS handshake.
-
SSL connect error,ERR_SSL_PROTOCOL_ERROR, orhandshake failure
These indicate a fundamental failure in the TLS negotiation process, often due to configuration issues on either the client or server side. -
CERTIFICATE_VERIFY_FAILEDorSSL certificate problem
These errors are often seen in clients like Python requests or cURL and indicate a problem with the certificate itself or the validation process. -
UNABLE_TO_GET_ISSUER_CERTorUNABLE_TO_VERIFY_LEAF_SIGNATURE
This happens when the server (or client) cannot build a complete, trusted chain from the presented certificate back to a known and trusted root Certificate Authority (CA). -
The user certificate is expired or blacklisted
The validating party has identified that the certificate's validity date is in the past, or it is present on a Certificate Revocation List (CRL). -
Unsupported certificate purposeorclient_cert_chain_invalid_eku
The client certificate does not have the required Extended Key Usage (EKU) attribute (specifically "Client Authentication") to be used for mTLS. -
No client certificate presentedorclient_cert_not_provided
The client did not send a certificate when the server requested one during the handshake. -
client_cert_invalid_rsa_key_sizeorclient_cert_unsupported_elliptic_curve_key
The certificate uses an algorithm or key size that is not supported by the validating system. -
hostname mismatch
The hostname in the server's certificate does not match the domain name the client is trying to connect to.
Updated 29 days ago

