• Updated
mTLS (Mutual TLS): How It Works, with Diagram
Mutual TLS (mTLS) is a security protocol that extends standard TLS by requiring both parties in a connection to authenticate each other using digital certificates. The server proves itself to the client, and the client proves itself right back.
This mutual authentication is what separates mTLS from standard TLS and makes it the dominant choice for securing machine-to-machine communication: microservices, API gateways, IoT devices, and zero trust architectures all rely on it.
What is TLS, and why isn’t it enough?
Before understanding mTLS, it helps to understand what standard TLS does, and what it leaves out.
TLS (Transport Layer Security) is the protocol that secures most internet traffic today. When your browser connects to https://ngrok.com, TLS is doing two things: authenticating the server (via its certificate) and encrypting the connection so nobody can read the data in transit.
That authentication is one-directional. The server proves its identity to you, but you don’t prove your identity to the server. For a public website, that’s fine: the server doesn’t need to know who you are just to serve a web page. Application-layer authentication (username and password) handles that.
For service-to-service communication, the situation is different. There’s no human logging in. Service A needs to know that the response it’s receiving is genuinely from Service B, not an attacker who has compromised the network and is intercepting calls. A shared secret or API key helps, but those can be stolen. A cryptographic certificate, backed by a trusted Certificate Authority, cannot be forged.
That’s the gap mTLS fills.
How does mTLS work?
The mTLS handshake extends the standard TLS handshake by adding a client certificate exchange step. Here’s the full sequence:
1. Handshake initiation
The client sends a ClientHello message to the server, advertising the TLS version and cipher suites it supports.
The server responds with a ServerHello and, critically, includes a CertificateRequest message asking the client to present its own certificate. This is the step that doesn’t exist in standard TLS.
2. Certificate exchange
The server sends its digital certificate to the client. This certificate contains the server’s public key and is signed by a Certificate Authority (CA) the client trusts.
The client then sends its own certificate to the server, containing the client’s public key, signed by a CA the server trusts.
3. Certificate verification
Both parties independently verify the other’s certificate:
- The client checks the server’s certificate against its trusted CA list, verifying the signature, expiry date, and hostname.
- The server checks the client’s certificate against its trusted CA list. If the client’s certificate isn’t valid or isn’t signed by a CA the server recognizes, the connection is rejected here, before any application data is sent.
This is where mTLS stops man-in-the-middle attacks. An attacker intercepting the connection cannot produce a valid certificate signed by your private CA without access to the CA’s private key.
4. Key exchange
Once both certificates are verified, the client and server use the exchanged public keys to derive a shared session key through a key agreement algorithm (typically ECDHE). Neither side transmits this session key directly. Each one computes it independently from the other’s public key and their own private key.
5. Encrypted communication
All subsequent data is encrypted using the shared session key. Even if someone intercepts the traffic, they cannot decrypt it without the private keys that were never transmitted.
The mTLS handshake diagram
The diagram below traces the same flow in six numbered steps: the hellos (1–2), the server’s certificate being verified by the client (3), the client’s certificate being verified by the server (4), the key exchange (5), and the encrypted session (6). Reading the flow this way makes the key point obvious: a client that can’t present a CA-signed certificate is rejected at step 4, before any application data moves.
Want to see this handshake succeed and fail for real? Skip to the hands-on walkthrough: you’ll generate a CA and client certificate, put an mTLS-protected endpoint in front of a local service, and watch curl get rejected without a certificate.
mTLS vs TLS: key differences
The core trade-off is complexity vs. assurance. Standard TLS is simpler to operate because only server certificates need managing. mTLS requires issuing, rotating, and revoking client certificates too, but in return you get cryptographic proof that both parties are who they claim to be.
mTLS authentication: how certificates work
The foundation of mTLS is X.509 digital certificates. Understanding these explains why mTLS is stronger than shared secrets or API keys.
Certificate Authorities (CAs) are the root of trust. A CA is an entity that issues certificates, signing each one with its private key to vouch for the certificate holder’s identity. In an mTLS setup, you typically run your own private CA, not a public CA like Let’s Encrypt, because you don’t want arbitrary clients on the internet to be able to obtain a certificate.
Certificate issuance works like this: a service generates a key pair (public + private), creates a Certificate Signing Request (CSR) containing its public key and identity information, and submits it to the CA. The CA verifies the identity and signs the certificate. The private key never leaves the service.
Certificate verification at handshake time asks: does this certificate chain back to a CA I trust? Is it expired? Has it been revoked?
Revocation is the Achilles heel of certificate-based auth. If a service’s private key is compromised, you need to revoke its certificate quickly. Two mechanisms handle revocation:
- OCSP (Online Certificate Status Protocol) lets the verifier query the CA in real time for a certificate’s current status.
- CRL (Certificate Revocation List) is a list of revoked certificates that the CA publishes and verifiers download periodically.
For production mTLS, automated certificate rotation, using short-lived certificates that expire every few hours or days, is increasingly preferred over revocation, because it limits the blast radius of a compromised key without depending on revocation infrastructure being available.
When to use mTLS
mTLS shines in environments where all participants are machines and you can control certificate issuance:
Microservices and service meshes. Service meshes like Istio and Linkerd use mTLS by default for all intra-cluster traffic. Every service gets a certificate, and mutual authentication happens transparently at the sidecar proxy layer.
API gateways. When your API gateway receives requests from partner services or internal clients, mTLS gives you cryptographic proof of which client is connecting. That’s stronger than API keys, which can be shared or leaked. See how ngrok works as an API gateway with mTLS for exactly this pattern.
Zero trust networks. Zero trust security assumes no implicit trust based on network location: every connection must be authenticated regardless of whether it’s internal or external. mTLS is the standard mechanism for enforcing this for machine identities.
IoT devices. Devices in the field can hold a certificate provisioned at manufacture time. When they connect home, mTLS verifies the device is genuine, not an attacker who has taken over the device’s IP address.
Webhooks and callbacks. If your service sends webhooks to customer endpoints, mTLS lets you verify the customer’s endpoint is authentic before sending sensitive data.
mTLS is generally not used for browser-to-server connections, because distributing client certificates to end users at scale is operationally difficult. For human-facing authentication, OAuth 2.0 and OpenID Connect are the standard choice.
mTLS challenges and limitations
Understanding the costs helps you decide when mTLS is worth it:
Certificate lifecycle management. Every service needs a certificate, and certificates expire. Automating issuance and rotation is critical, because manual certificate management at scale is a source of outages, not security.
Debugging. Encrypted connections with mutual auth are harder to inspect than plain HTTP. Tools like ngrok’s Traffic Inspector help here by capturing the decrypted request/response at the gateway layer before forwarding to your upstream.
CA infrastructure. Running a private CA requires operational care. Compromise of the CA’s private key means all certificates it has signed must be considered untrusted. Keep CA keys in a hardware security module (HSM) or a secrets manager with tight access controls.
Performance. The additional certificate verification during the handshake adds a few milliseconds of latency compared to standard TLS. For long-lived connections this is negligible; for high-frequency short-lived connections it can accumulate.
How to implement mTLS with ngrok
ngrok’s terminate-tls Traffic Policy action puts mTLS in front of any service without changing your application code. ngrok verifies the client certificate at its edge, rejects anything not signed by your CA, and forwards only authenticated traffic to your upstream. It’s the same building block behind ngrok’s secure customer connectivity, where mutual TLS authenticates both ends of a private link.
The whole thing takes about five minutes. You’ll need openssl, curl, and an ngrok account on the Pay-as-you-go plan, which is where mTLS is available. Its monthly fee counts as a credit against usage, so trying this costs effectively nothing.
1. Generate a CA and a client certificate
If you already run a private CA, skip this and use your existing CA certificate.
2. Write the Traffic Policy
Paste the contents of ca.crt into policy.yml. The second rule is optional: it passes the verified client’s identity to your upstream as a header, which ngrok does not do on its own.
3. Start an mTLS-protected endpoint
Point ngrok at any local service, for example one on port 8080:
4. Test it
Use the URL ngrok prints. Without a client certificate, the handshake fails before any request reaches your service:
With the certificate signed by your CA, the request goes through, and your service sees x-client-cn: ExampleClient:
That’s mutual TLS end to end: your CA decides who gets in, and ngrok enforces it at the edge.
For uploading your CA to the dashboard instead of inlining it, matching on other certificate fields, and terminating mTLS at the agent instead of the edge, see the mTLS termination docs. To put mTLS in front of an API, see mTLS for API gateways.
Ready to try it? Create an ngrok account and you’ll have an mTLS-protected endpoint running in minutes.
Frequently asked questions
mTLS (mutual TLS) is a security protocol that extends standard TLS by requiring both the client and server to authenticate each other using digital certificates. In standard TLS, only the server proves its identity. In mTLS, both sides present and verify certificates before any data is exchanged.
Standard TLS is one-way: only the server presents a certificate. mTLS is two-way: both the client and the server exchange and verify certificates against a trusted Certificate Authority. This mutual authentication makes mTLS significantly stronger for machine-to-machine communication where you cannot rely on user login credentials.
The mTLS handshake works in five steps: (1) the client sends a ClientHello to initiate the connection, (2) the server responds with its certificate and requests the client's certificate, (3) the client presents its own certificate, (4) both parties verify each other's certificates against a trusted Certificate Authority, and (5) they derive shared session keys and begin encrypted communication.
An mTLS diagram maps the mutual TLS handshake flow: the client's ClientHello, the server presenting its certificate and issuing a CertificateRequest, the client returning its own certificate, both sides verifying each certificate against a trusted Certificate Authority, and the shared session key that encrypts everything afterward. Seeing the flow visually makes clear why an attacker without a CA-signed certificate is rejected before any data is exchanged.
Yes. Because both parties must present valid certificates signed by a trusted Certificate Authority, an attacker cannot impersonate either side without access to a legitimate certificate. A man-in-the-middle attacker fails certificate verification and the connection is rejected before any data is sent.
mTLS is considered highly secure for machine-to-machine communication. The protocol itself is sound; the main operational risk is certificate lifecycle management. A compromised certificate must be revoked quickly via OCSP or CRL. Used with short-lived certificates and automated rotation, mTLS is one of the strongest authentication mechanisms available.
mTLS is best suited for service-to-service communication where both sides are machines: microservices architectures, API-to-API calls, zero trust network access, IoT device authentication, and service mesh environments. It is not typically used for browser-to-server connections because distributing client certificates to end users is operationally complex.
The main benefits of mTLS are: mutual authentication (both sides are cryptographically verified), strong protection against impersonation and man-in-the-middle attacks, encrypted data in transit, alignment with zero trust security principles, and an auditable certificate record for compliance.
mTLS authentication is the process by which both the client and server verify each other's identity using X.509 digital certificates issued by a trusted Certificate Authority. Unlike password-based authentication, mTLS uses asymmetric cryptography: each party proves possession of a private key without ever transmitting it, making credentials impossible to intercept or brute-force.
Related posts
Terminate TLS however (and wherever) you want with Traffic Policy
Need custom certs? Want fast mTLS setup? ngrok’s terminate-tls action gives you complete TLS control from one declarative config.
Authentication with ngrok
Add authentication to any ngrok endpoint in minutes with Traffic Policy. Choose Basic Auth, OAuth login, OpenID Connect, or JWT validation, no code required.