What is mutual TLS (mTLS) client authentication in Kafka, and how does it differ from plain TLS encryption?
answer
- one-way = broker cert only
- mTLS = client cert too
- ssl.client.auth=required
- keystore = me, truststore = them
- principal from cert DN
basics
~20 sWith plain TLS, only the broker proves its identity with a certificate. With mutual TLS, the client ALSO presents its own certificate, so the broker authenticates the client. The client's certificate identity becomes its Kafka principal.
solid answer
~50 sPlain TLS gives you an encrypted channel and one-way authentication: the broker presents a server certificate that the client validates against a trusted CA, so the client knows it is talking to the real broker. Mutual TLS (two-way SSL) adds the reverse direction: during the TLS handshake the broker also requests a certificate from the client, and the client sends one from its keystore. The broker validates that client certificate against its truststore (the CA chain) and, if valid, treats the client as authenticated. Kafka then derives a principal from the certificate's Subject DN (by default the full DN). You enable it on the broker with the listener config `ssl.client.auth=required`. So mTLS is authentication on top of the encryption that TLS already provides — it answers 'who is this client?', not just 'is the channel encrypted?'.
go deeper
Know that mTLS means both sides show certificates and the broker learns who the client is.
Know the three ssl.client.auth values and the keystore/truststore split on both client and broker.
Explain the handshake direction, ANONYMOUS fallback under 'requested', and that principal derives from the cert DN feeding ACLs.
Reason about when to use cert-based identity vs SASL, operational cert lifecycle, and the separation of encryption/authentication/authorization layers.
## Background: TLS in Kafka Kafka clients and brokers can talk over TLS (often still called 'SSL' in config keys). TLS does two things: it **encrypts** the traffic so eavesdroppers can't read it, and it lets one party **authenticate** the other using X.509 certificates. An **X.509 certificate** is a signed document binding an identity (a 'Distinguished Name' or **DN**, e.g. `CN=payments-service,OU=apps,O=Acme`) to a public key. It is signed by a **Certificate Authority (CA)**. You trust a certificate if you trust the CA that signed it. - A **keystore** holds your own private key + certificate (your identity, what you present). - A **truststore** holds the CA certificates you trust (used to validate the *other* side's certificate). ## One-way TLS vs mutual TLS **One-way (plain) TLS:** During the handshake the **broker** sends its server certificate. The client validates it against the client's truststore. Now the channel is encrypted and the client trusts the broker. But the broker has **no idea who the client is** — anyone who can reach the port and trust the broker's CA can connect. **Mutual TLS (two-way SSL, mTLS):** In addition to the above, the broker **requests a certificate from the client**. The client presents its certificate from its keystore. The broker validates it against the broker's truststore. If valid, the broker now has an authenticated identity for the client. This is **authentication**, distinct from encryption. ## How you turn it on On the broker listener you set `ssl.client.auth`: - `none` — don't ask for a client cert (plain one-way TLS). - `requested` — ask, but allow clients that don't present one (the connection is then unauthenticated for that client). - `required` — ask, and **reject** any client that doesn't present a valid cert. For real authentication you use `required`. The client must be configured with a keystore (`ssl.keystore.location`, `ssl.keystore.password`, `ssl.key.password`) plus a truststore to validate the broker. ## What the identity becomes After a successful mTLS handshake, Kafka builds a **KafkaPrincipal** from the client certificate's Subject DN. By default the principal is `User:<full DN>`, e.g. `User:CN=payments-service,OU=apps,O=Acme`. ACLs (authorization rules) are then written against that principal. (Extracting a cleaner principal from the DN is done with `ssl.principal.mapping.rules`, covered separately.) ## Edge cases / gotchas - mTLS authenticates the **connection/identity**, it does not by itself authorize anything — you still need ACLs. - If `ssl.client.auth=requested` and a client sends no cert, it connects as the **ANONYMOUS** principal; ACLs may then deny it, which can look confusing. - Encryption and authentication are separable: you can have TLS encryption with SASL doing the authentication instead of client certs. mTLS specifically means certs do the authenticating.
- Which config makes the broker reject clients that don't present a certificate?`ssl.client.auth=required` on the listener. `requested` would let certless clients through as ANONYMOUS; `none` disables client-cert auth entirely.
- Does mTLS replace the need for ACLs?No. mTLS only authenticates the client (establishes 'who'). You still need an authorizer and ACLs to control what that principal is allowed to do.
saying these in an interview costs you the question
- Saying TLS and mTLS are the same thing — mTLS adds client-side authentication.
- Claiming mTLS handles authorization — it only authenticates identity.
- Confusing keystore (your identity) with truststore (CAs you trust).