You secure a cross-cluster MM2 link with mutual TLS. How is the Kafka principal derived from the client certificate, and how do you control it with ssl.principal.mapping.rules?
answer
- Default principal = full DN
- ssl.principal.mapping.rules = broker-side regex RULE:.../$1/
- Extract CN, end with DEFAULT
- Each cluster maps independently → must converge
- Kerberos analog: kerberos.principal.to.local.rules
basics
~20 sWith mTLS the broker takes the client certificate's full Distinguished Name (DN) as the principal by default, e.g. 'User:CN=mm2,OU=...,O=...'. ssl.principal.mapping.rules lets you rewrite that DN with regex into a shorter principal like 'User:mm2' that your ACLs reference.
solid answer
~40 sWhen a client connects with mutual TLS, the broker authenticates it by validating the certificate chain against its truststore, then builds a `KafkaPrincipal` from the certificate's subject **Distinguished Name**. By default the principal is the entire DN: `User:CN=mm2,OU=replication,O=Acme,L=...,C=US`. ACLs must then match that exact string, which is brittle. The broker config `ssl.principal.mapping.rules` is an ordered list of `RULE:` transforms (same syntax family as Kerberos `auth_to_local`) that apply a regex to the DN and emit a normalized principal — typically extracting just the CN: `RULE:^CN=(.*?),.*$/$1/`, ending with `DEFAULT`. So `CN=mm2,OU=...` becomes `User:mm2`, and your ACLs reference `User:mm2`. This is the cross-cluster crux: source and target clusters issue different certs/DNs, so each cluster's mapping rules must converge MM2's identity onto the principal names that its own ACLs grant.
go deeper
Know mTLS authenticates the client cert and that the principal comes from the certificate DN.
Write a basic RULE to extract CN and understand it ends with DEFAULT.
Reason about per-cluster PKIs, broker-side evaluation, and convergence of MM2's principal onto each cluster's ACLs.
Standardize DN/SAN conventions and mapping-rule patterns org-wide so identities are stable and auditable across many clusters.
## Background: what mutual TLS authenticates In one-way TLS only the **server** (broker) proves its identity. In **mutual TLS (mTLS)** the **client** also presents a certificate, and the broker validates it against the broker's **truststore** (the set of trusted CA certificates). If the chain validates and isn't expired/revoked, the client is authenticated. But authentication only proves the cert is valid — Kafka still needs to turn the certificate into an **identity it can authorize**. That identity is a `KafkaPrincipal`, written `User:<name>`. ## Default principal = the whole DN A certificate's **subject** is a **Distinguished Name (DN)**: an ordered set of attributes like `CN` (Common Name), `OU` (Organizational Unit), `O` (Organization), `L`, `C`. By default Kafka uses the *entire* DN as the principal name, e.g.: ``` User:CN=mm2,OU=replication,O=Acme Corp,L=NYC,ST=NY,C=US ``` Problems: it's long, it embeds attributes that change when you re-issue certs (new OU, new location), and any drift breaks every ACL that hard-codes the string. ## ssl.principal.mapping.rules This **broker** property (not a client property) post-processes the DN into a clean principal. It's an ordered, comma-separated list of rules: ``` ssl.principal.mapping.rules=RULE:^CN=(.*?),.*$/$1/ , DEFAULT ``` Each `RULE:pattern/replacement/[LU]`: - `pattern` is a regex applied to the DN. - `replacement` builds the principal name using capture groups (`$1`, `$2`). - optional trailing `L` (lowercase) or `U` (uppercase). Rules are tried **in order**; the first match wins. `DEFAULT` (use the full DN) should be last as a fallback. The example above extracts the CN, so `CN=mm2,OU=replication,...` → principal name `mm2` → `KafkaPrincipal` `User:mm2`. ## Why this matters specifically across clusters MM2 connects to **two** clusters that are usually administered separately, with **different PKIs**. The source cluster's CA might issue MM2 a cert with DN `CN=mm2-source,OU=...`, while the target's CA issues `CN=mm2-target,OU=...`. Each cluster: 1. Validates MM2's cert against **its own** truststore (so MM2 may need different keystores per side — `source.ssl.keystore.location` vs `target.ssl.keystore.location`). 2. Maps the DN to a principal via **its own** `ssl.principal.mapping.rules`. 3. Grants ACLs to **that** principal. Getting principal mapping consistent on both ends is the practical core of 'principal mapping across clusters'. If the rule on the target doesn't fire, ACLs written for `User:mm2` silently never match the actual principal `User:CN=mm2-target,...`, and replication fails with authorization errors that look like a missing ACL. ## SASL analog For SASL/GSSAPI (Kerberos) the equivalent is `sasl.kerberos.principal.to.local.rules`. For SASL/SCRAM and PLAIN the principal is simply the username; for OAUTHBEARER it comes from a configurable claim. Each cluster maps independently. ## Edge cases / gotchas - Mapping rules are evaluated **broker-side at authentication time**; changing them requires a broker restart (they're not dynamic). - A too-greedy regex can collapse two distinct certs onto the **same** principal, silently widening access — keep rules tight and test with `kafka-acls`/authorizer logs. - DN attribute **ordering and escaping** (RFC 2253) matters; commas inside values must be accounted for in the regex. - Certificate **revocation** (CRL/OCSP) is separate from principal mapping; a mapped principal still works until the cert is rejected by the chain check.
- Is ssl.principal.mapping.rules a client or broker config?Broker config. The broker derives the principal at authentication time, so the mapping lives on each broker and requires a restart to change. The client only supplies the certificate.
- What goes wrong if the source and target clusters map MM2's DN to different principal names?Nothing inherently — that's expected. You just have to grant the correct per-cluster principal in each cluster's ACLs. The failure mode is forgetting and writing ACLs for a principal the mapping never actually produces.
saying these in an interview costs you the question
- Claiming the principal is taken from the certificate's CN automatically (it's the full DN unless you add mapping rules)
- Saying ssl.principal.mapping.rules is a client-side setting
- Assuming one mapping rule set covers both clusters when they have separate PKIs
- Using an overly broad regex that collapses multiple identities into one principal