Mutual TLS (mTLS) is often described as a handshake where both parties verify each other’s identity, but the real power comes from the fact that it shifts authentication from "who are you?" (username/password, tokens) to "are you who you claim to be, and are you allowed to be here?"

Let’s see this in action. Imagine you have an API Gateway protecting a backend service. Normally, a client sends a request with a bearer token. The Gateway validates the token and forwards the request.

Client -> API Gateway: GET /users/123
  Headers:
    Authorization: Bearer <some_long_token>

API Gateway -> Backend Service: GET /users/123
  Headers:
    Authorization: Bearer <some_long_token>

With mTLS, the client and Gateway establish a secure channel before any application data is exchanged. The client presents its certificate, and the Gateway validates it. Then, the Gateway presents its certificate to the client. This is often overlooked: the server also needs to authenticate itself to the client. The client then forwards the request, but now the Gateway can use the validated client identity to authorize the request.

Client <-> API Gateway (TLS handshake with mTLS)
  Client presents its certificate.
  API Gateway validates Client certificate.
  API Gateway presents its certificate.
  Client validates API Gateway certificate.

Client -> API Gateway: GET /users/123
  (Now part of the established TLS connection)

API Gateway -> Backend Service: GET /users/123
  Headers:
    X-Client-CN: user123
    X-Client-SAN: user123.example.com

Notice the X-Client-CN and X-Client-SAN headers. These are populated by the API Gateway based on the validated client certificate and are used by the backend service for authorization.

The problem mTLS solves is moving trust from opaque, potentially compromised tokens to cryptographically verifiable identities. A stolen bearer token can be used by anyone. A stolen client certificate can be used, but only if the attacker also has the corresponding private key, and the certificate itself is tied to a specific entity (like a service instance or a user’s device). This makes it much harder for unauthorized parties to impersonate clients.

Internally, this involves a few key components. First, a Certificate Authority (CA) is needed. This CA signs the certificates for both the API Gateway and all its clients. The API Gateway needs to trust the CA that signed the client certificates. This trust is configured in the Gateway’s mTLS settings, typically by uploading the CA’s public certificate.

For the API Gateway itself, it needs its own certificate and private key, signed by a CA that the clients trust. This is the standard TLS part, but with mTLS, the client also performs validation on the Gateway’s certificate.

The configuration on an API Gateway (like AWS API Gateway or Kong) involves specifying:

  1. The truststore for client certificates: This is the CA certificate that the Gateway will use to verify incoming client certificates.
  2. The certificate and private key for the Gateway itself: This is what the Gateway presents to clients.
  3. The verification mode: Typically "REQUIRED" for mTLS.
  4. How to extract client identity: Often via the Subject Alternative Name (SAN) or Common Name (CN) fields in the client certificate.

When a client initiates a connection, the Gateway requests a client certificate. The client’s TLS stack (e.g., OpenSSL, Java Security) picks the appropriate certificate and its private key and sends it. The Gateway then uses its configured truststore to verify the certificate’s signature and check if it’s expired or revoked. If verification passes, the Gateway extracts information like the CN or SAN and can then use these values to make authorization decisions.

A common pitfall is assuming that just enabling mTLS on the Gateway is enough. The backend services still need to be configured to trust the identity provided by the Gateway. If the backend blindly accepts requests forwarded by the Gateway without checking the X-Client-CN or X-Client-SAN headers, the mTLS enforcement is effectively bypassed at the application layer. The Gateway might enforce mTLS, but the backend might not enforce the authorization based on that identity.

The most surprising true thing about mTLS is that it’s not just about encrypting traffic; it’s fundamentally a cryptographic identity verification mechanism that can replace or augment traditional authentication and authorization schemes with a much stronger, harder-to-forge foundation. The fact that the server also authenticates itself to the client during the mTLS handshake is crucial for preventing man-in-the-middle attacks where a malicious intermediary might try to present a fake server certificate, even if the client is properly presenting its own.

Once mTLS is robustly enforced, the next logical step is to leverage the rich identity information extracted from the client certificates for fine-grained authorization policies within the API Gateway or backend services.

Want structured learning?

Take the full Apigateway course →