How-to

How to Set Up SSL Client Certificate Authentication

Setting up client certificate authentication (the server side of mutual TLS) means configuring your web server to request, and optionally require, a certificate from connecting clients, validated against a CA you trust for that purpose — typically a private, internal CA rather than a public one.

Nginx example

ssl_client_certificate /etc/nginx/ssl/client-ca.pem;
ssl_verify_client on;

ssl_client_certificate points to the CA certificate(s) you trust for validating client certificates. ssl_verify_client on requires a valid client certificate for the connection to succeed at all; setting it to optional instead lets you inspect and act on the certificate at the application level without rejecting connections that don't present one.

Apache example

SSLVerifyClient require
SSLCACertificateFile /etc/apache2/ssl/client-ca.pem

For either server, you'll separately need a process for issuing client certificates from your private CA to each legitimate client, and a plan for rotating and revoking them — the server-side configuration above is only half of a working mTLS setup.

What to do if legitimate clients are being rejected despite having valid certificates

A legitimate client rejection usually points to the server not trusting the specific CA that issued the client's certificate — confirming your server's client-CA trust configuration includes the correct CA certificate is the most common fix for this specific symptom.

How to generate and distribute client certificates to legitimate users

Client certificates are typically issued by a private, internally-operated CA specifically set up for this purpose, then securely distributed to authorized users or devices — this is a distinct issuance process from public certificate authorities, since client certificates authenticate specific individuals or devices rather than public-facing domains.

What certificate revocation checking means specifically for client certificates

Just as with server certificates, a compromised or no-longer-authorized client certificate should be revoked, and your server's mTLS configuration should be checking revocation status (via CRL or OCSP) for client certificates, not just accepting any certificate signed by the trusted client CA regardless of its current status.

How to combine client certificate authentication with additional application-level authorization

mTLS at the transport layer confirms a connecting client possesses a valid, trusted certificate, but doesn't inherently determine what that specific client is authorized to do — combining it with application-level authorization checks (verifying the certificate's specific identity against a permissions system) provides both authentication and fine-grained authorization together.

Why client certificate expiry needs its own tracking separate from server certificates

Client certificates, often issued with different validity periods and through an entirely separate private CA than your server certificates, need their own independent expiry tracking — assuming your server certificate monitoring covers client certificates too is a common oversight in mTLS deployments.

What to do if mTLS breaks an existing API integration that previously worked without it

Enabling mTLS on an endpoint previously accessible without a client certificate will break any existing client not yet provisioned with one — planning a transition period where both mTLS and standard access are temporarily supported, or coordinating client certificate distribution before enforcing mTLS, avoids an abrupt, breaking change for existing integrations.

How to test client certificate authentication without needing a full application setup

Testing mTLS directly with OpenSSL's s_client, providing your client certificate and key via the -cert and -key flags, confirms the server-side mTLS configuration is working correctly at the protocol level before involving any application-specific client software.

A closing note on mTLS as a deliberate architectural choice, not a default

mTLS adds real operational overhead (certificate issuance, distribution, and lifecycle management for every client) that's only worth taking on for genuinely high-security service-to-service scenarios — a deliberate architectural choice rather than something to apply by default across every API or service.

A final thought on building a genuine lifecycle process

Building a clear internal process for issuing, renewing, and revoking client certificates, mirroring the same lifecycle discipline covered for server certificates throughout this site, prevents client certificate management from becoming an ad-hoc, inconsistently handled afterthought.