skip to content

How do you configure sasl.jaas.config on a Kafka client and broker for PLAIN vs SCRAM, and what login modules are used?

level: middleimportance: should knowfreq 50%

answer

  1. PlainLoginModule vs ScramLoginModule
  2. inline sasl.jaas.config ... required username=.. password=..;
  3. broker PLAIN: user_<name>="pw" entries (restart to add)
  4. SCRAM broker JAAS = only inter-broker identity
  5. listener.name.<l>.<mech>.sasl.jaas.config per-listener
  6. trailing semicolon required

basics

~10 s

Set sasl.jaas.config inline. PLAIN uses PlainLoginModule, SCRAM uses ScramLoginModule, each with username/password. On the broker, the KafkaServer JAAS section defines accepted users (PLAIN) or the inter-broker login.

solid answer

~40 s

Kafka uses JAAS (Java Authentication and Authorization Service) login modules. The modern approach is an inline per-listener property `sasl.jaas.config` rather than a global JAAS file. For a PLAIN client: `sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required username="alice" password="secret";`. For SCRAM: `org.apache.kafka.common.security.scram.ScramLoginModule required username="alice" password="secret";`. Also set `security.protocol=SASL_SSL` and `sasl.mechanism=PLAIN` or `SCRAM-SHA-256`. On the broker, the `KafkaServer` JAAS context (or per-listener `listener.name.<name>.<mechanism>.sasl.jaas.config`) configures the inter-broker login and, for PLAIN, the static list of accepted `user_<name>="<password>"` entries inside PlainLoginModule. SCRAM brokers don't list users in JAAS — users live in ZK/KRaft — but the broker still needs a ScramLoginModule entry with its own inter-broker credentials. Per-listener inline config is preferred so different listeners can use different mechanisms.

go deeper

for a junior

Recognize that sasl.jaas.config names a login module with username and password.

for a middle

Write correct client and broker JAAS for both PLAIN and SCRAM and know PLAIN lists users while SCRAM doesn't.

for a senior

Use per-listener prefixed JAAS to mix mechanisms and explain the inter-broker identity vs client user distinction.

for a principal

Architect multi-listener auth (internal SCRAM, external OAUTHBEARER) and design away PLAIN's restart-to-add-user limitation.

## JAAS basics **JAAS** (Java Authentication and Authorization Service) is the Java standard Kafka builds on. A *login module* is a class that knows how to obtain/verify credentials for one mechanism. The two relevant modules: - `org.apache.kafka.common.security.plain.PlainLoginModule` — for `PLAIN`. - `org.apache.kafka.common.security.scram.ScramLoginModule` — for `SCRAM-SHA-256` / `SCRAM-SHA-512`. ## Two ways to supply JAAS 1. **Static JAAS file** via `-Djava.security.auth.login.config=/path/kafka_jaas.conf` with named contexts (`KafkaServer { ... };`, `KafkaClient { ... };`). Older style. 2. **Inline `sasl.jaas.config` property** (preferred) — a single line, ending with a semicolon, set per client or per broker listener. This avoids a separate file and supports per-listener mechanisms. ## Client config PLAIN client: ``` security.protocol=SASL_SSL sasl.mechanism=PLAIN sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required \ username="alice" password="alice-secret"; ``` SCRAM client: ``` security.protocol=SASL_SSL sasl.mechanism=SCRAM-SHA-256 sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required \ username="alice" password="alice-secret"; ``` Note: the client always supplies a *cleartext* password in its own config (it must, to compute the SCRAM proof or send the PLAIN credential) — the 'never on the wire' guarantee of SCRAM is about the **network**, not the client's local config. ## Broker config The broker's `KafkaServer` JAAS context covers (a) the inter-broker login identity and (b) for PLAIN, the **list of valid users**. PLAIN broker (static user list): ``` listener.name.sasl_ssl.plain.sasl.jaas.config=\ org.apache.kafka.common.security.plain.PlainLoginModule required \ username="admin" password="admin-secret" \ user_admin="admin-secret" \ user_alice="alice-secret"; ``` Here `username/password` is the broker's own (inter-broker) credential, and each `user_<name>="<pw>"` adds an accepted client. Adding a user means editing this and restarting the broker — the big operational downside of PLAIN. SCRAM broker: ``` listener.name.sasl_ssl.scram-sha-256.sasl.jaas.config=\ org.apache.kafka.common.security.scram.ScramLoginModule required \ username="admin" password="admin-secret"; ``` No `user_*` entries — client users are managed in ZK/KRaft via kafka-configs. The `username/password` here is only the broker's inter-broker SCRAM identity (which must be provisioned in metadata). ## Per-listener prefix The property name `listener.name.<listenerName>.<mechanism>.sasl.jaas.config` lets each listener use a distinct mechanism/credentials — e.g., an internal listener using SCRAM and an external one using OAUTHBEARER. This per-listener override is the recommended modern pattern over a single global file. ## Common mistakes - Forgetting the trailing semicolon in `sasl.jaas.config` (causes a parse error). - Setting `security.protocol=SASL_PLAINTEXT` with PLAIN in production (leaks the password). - Expecting SCRAM brokers to list users in JAAS (they don't).

  • Why does a SCRAM broker JAAS config not list client users, but a PLAIN broker config does?
    PLAIN has no dynamic credential store, so accepted users are hardcoded as user_<name> entries in JAAS and require a restart to change. SCRAM stores users in ZK/KRaft metadata managed by kafka-configs, so the broker JAAS only needs the broker's own inter-broker identity.
  • How do you let one broker offer different SASL mechanisms on different listeners?
    Use the per-listener prefixed property listener.name.<listenerName>.<mechanism>.sasl.jaas.config and set sasl.enabled.mechanisms appropriately, so e.g. an internal listener uses SCRAM-SHA-512 while an external one uses OAUTHBEARER.

saying these in an interview costs you the question

  • Saying SCRAM clients don't need a password in their local config (they do — it's the network that's protected)
  • Listing client users in a SCRAM broker's JAAS
  • Omitting the trailing semicolon in sasl.jaas.config
  • Confusing the broker's inter-broker username/password with the client user list

context