The most surprising thing about TLS client certificate authentication is that it’s not about proving who you are, but about proving who the server is to you.

Let’s look at how this plays out with mTLS (mutual TLS). Imagine a client application, curl, trying to access a protected service running on api.example.com.

curl --cert client.pem --key client.key --cacert ca.pem https://api.example.com/data

When curl initiates the connection, the server api.example.com presents its certificate. curl verifies this certificate against the ca.pem (the Certificate Authority that issued the server’s certificate). If that check passes, the server has proven its identity to curl. This is standard TLS.

Now, for mTLS, the server api.example.com also requests a certificate from curl. curl then presents its own certificate (client.pem) and its private key (client.key) to the server. The server, in turn, verifies curl’s certificate against its own trust store (which would contain the CA that issued client.pem). If both sides successfully validate each other’s certificates, the connection is established. The client has proven its identity to the server, and the server has proven its identity to the client.

This setup is often used for securing internal microservices, B2B integrations, or any scenario where strong, cryptographically verified identity is paramount, and you don’t want to rely solely on username/password or API keys.

Here’s a simplified breakdown of the handshake:

  1. Client Hello: curl sends a "hello" message, indicating TLS version and supported cipher suites.
  2. Server Hello: api.example.com responds with its chosen TLS version and cipher suite. It also sends its server certificate.
  3. Server Certificate Verification (Client): curl checks if the server certificate is valid and signed by a trusted CA (from ca.pem).
  4. Client Certificate Request (Server): api.example.com requests a client certificate.
  5. Client Certificate & Key Exchange: curl sends its client certificate (client.pem) and its private key (client.key) to the server.
  6. Client Certificate Verification (Server): api.example.com checks if the client certificate is valid and signed by a trusted CA.
  7. Key Exchange & Encryption: Both sides use the verified certificates to securely exchange a symmetric session key, which is then used to encrypt all subsequent communication.

The key components you’ll be managing are:

  • Certificate Authority (CA): The root of trust. You’ll need a CA to sign both server and client certificates. This can be a public CA, an internal enterprise CA, or even a self-signed CA for development/testing.
  • Server Certificate & Key: Issued by the CA, identifying the server (api.example.com).
  • Client Certificate & Key: Issued by the CA, identifying the client (curl or your application).

Consider a common configuration for an Nginx server acting as the mTLS endpoint. The relevant directives in nginx.conf (or a site-specific conf file) might look like this:

server {
    listen 443 ssl;
    server_name api.example.com;

    ssl_certificate /etc/nginx/ssl/api.example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/api.example.com.key;

    # mTLS specific directives
    ssl_client_certificate /etc/nginx/ssl/ca.crt; # CA that signed client certs
    ssl_verify_client on; # or 'optional' if you want to allow unauthenticated access too

    # ... other proxy settings ...
}

Here, ssl_client_certificate points to the CA certificate that Nginx will use to verify incoming client certificates. ssl_verify_client on; enforces that a valid client certificate must be presented for the connection to proceed.

The most counterintuitive part of mTLS is often the management of the trust stores. While the server needs to trust the CA that issued the client certificates, the client also needs to trust the CA that issued the server certificates. This means both parties must have a copy of the appropriate CA certificate in their respective trust stores. A common mistake is to only configure the server-side trust for client certs and forget that the client also needs to validate the server cert.

The next step after successfully setting up mTLS is often integrating it with an authorization layer, where the validated client identity is used to grant or deny access to specific resources.

Want structured learning?

Take the full Tls-ssl course →