Short answer
mTLS (mutual TLS) is TLS where both parties authenticate with a certificate — not only the server. During the handshake the server asks the client for a certificate, and the client asks for the server's as usual. Both sides validate the peer's certificate against a trusted CA. The connection is established only if both certificates are valid, unexpired and issued by a CA each side trusts. mTLS is used to secure service-to-service communication, APIs and anywhere you want to prove who is calling — not merely that the line is encrypted.
mTLS vs ordinary TLS: what is the difference?
Ordinary TLS (what your browser uses on https) authenticates only the server. You know you are talking to the real example.com, but example.com does not know who you are — that is decided afterwards with, say, a login and a cookie. mTLS moves client identity down into the transport layer itself:
| Ordinary TLS | mTLS | |
|---|---|---|
| Server proves identity | Yes | Yes |
| Client proves identity | No | Yes |
| Encryption | Yes | Yes |
| Typical use | Public websites | Service-to-service, APIs, Zero Trust |
We go deeper in mTLS vs ordinary TLS.
How mTLS extends the handshake
A normal TLS handshake negotiates protocol and cipher suite and verifies the server's certificate. mTLS adds two messages: the server sends a CertificateRequest, and the client responds with its own Certificate plus a CertificateVerify that proves the client owns the matching private key. You can see the server's request in s_client output as Acceptable client certificate CA names — the list of CAs whose client certificates the server will accept.
Try it: create an internal CA and a client certificate
mTLS requires a CA that issues client certificates. For internal use you typically run your own. Here we create a CA and sign a client certificate with the right Extended Key Usage:
# 1) Create an internal CA openssl req -x509 -newkey rsa:4096 -nodes -keyout ca.key -out ca.crt \ -days 3650 -subj "/CN=Internal Root CA" # 2) Create a client key + CSR openssl req -newkey rsa:2048 -nodes -keyout client.key -out client.csr \ -subj "/CN=service-a" # 3) Sign the client certificate with the clientAuth EKU openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial \ -out client.crt -days 365 \ -extfile <(printf "extendedKeyUsage=clientAuth")
Note extendedKeyUsage=clientAuth — without it many servers reject the certificate as unsuitable for client authentication.
Require a client certificate on the server (nginx)
In nginx, mTLS is enabled with three directives: point at the CA that should validate clients, and make verification mandatory:
server {
listen 443 ssl;
server_name api.example.com;
ssl_certificate /etc/ssl/api/fullchain.pem;
ssl_certificate_key /etc/ssl/api/privkey.pem;
# mTLS: require and validate a client certificate against our CA
ssl_client_certificate /etc/ssl/api/ca.crt;
ssl_verify_client on;
ssl_verify_depth 2;
location / {
# pass the client identity through to the backend
proxy_set_header X-Client-DN $ssl_client_s_dn;
proxy_set_header X-Client-Verify $ssl_client_verify;
proxy_pass http://backend;
}
}
ssl_verify_client on rejects any connection without a valid client certificate. With optional you allow anonymous clients but can still read $ssl_client_verify in your application and decide access there.
Connect as a client (curl)
A client must now send its certificate and key:
curl --cert client.crt --key client.key \
--cacert ca.crt \
https://api.example.com/health
Omit --cert/--key and the server rejects the handshake — and the error is often a cryptic sslv3 alert handshake failure. See our guide to troubleshooting mTLS.
When should you use mTLS?
- Service-to-service inside a cluster — where you want each service to prove its identity, not merely share a network. See mTLS in Kubernetes.
- API gateway → backend — so the backend only accepts traffic from the gateway. See mTLS between API gateway and backend.
- Machine-to-machine APIs where a certificate is stronger and more auditable than an API token. Compare with OAuth2 client credentials.
- Zero Trust architecture where no network is trusted and every connection must be authenticated. See mTLS and Zero Trust.
For browser-based access there are also client certificates in browsers, but that is a niche with its own UX.
The hidden burden: many more certificates
mTLS is strong security, but the price is certificate sprawl. Suddenly every service, every client and every internal CA has its own certificate with its own expiry date. An expired client certificate breaks an integration just as effectively as an expired server certificate — but it is noticed far less often, because no browser warns about it.
How CertControl keeps track of your mTLS certificates
CertControl discovers and monitors certificates across your estate — including client certificates and certificates issued by internal CAs. The platform tracks every expiry date, validates that chains are complete, and alerts you in good time before any certificate expires, whether it sits on a server or inside a service-to-service client. So an expired mTLS certificate never becomes the next production outage nobody saw coming.
Frequently asked questions
What does mTLS stand for?
Mutual TLS. "Mutual" refers to both parties (server and client) authenticating with a certificate, as opposed to ordinary TLS where only the server does so.
Is mTLS more secure than ordinary TLS?
It adds an extra guarantee: the server knows who the client is at the transport layer already. That prevents unauthorised clients from even establishing a connection. But it does not replace authorisation — you still need to decide what an authenticated client is allowed to do.
Should I use a public CA for mTLS?
Almost never. Client certificates for mTLS are typically issued by an internal CA you control, because you then decide exactly which clients are valid. Public CAs do not normally issue clientAuth certificates for arbitrary internal names.
What is the difference between mTLS and an API token?
An API token is a shared secret sent in a header; an mTLS certificate proves ownership of a private key without sending the secret. Certificates expire and can be revoked via a CA, and identity is bound to the transport layer. See the comparison with OAuth2 client credentials.
What happens when a client certificate expires?
The handshake fails and the client cannot connect — usually with a handshake error rather than a friendly message. That is why monitoring client-certificate expiry is just as important as for server certificates.
Can I run mTLS and ordinary TLS on the same server?
Yes. You can require a client certificate only on certain paths or server blocks (e.g. /api) and leave the rest open. In nginx this is controlled with ssl_verify_client per location or per server.