keepcalculator

06 Numbers and Powers

Kafka SASL: Plain vs SCRAM with TLS Explained

Card No. 06·4593 · Updated · Standard formula, shown below

To configure Kafka authentication with TLS, you choose between SASL/PLAIN and SASL/SCRAM based on your security needs: PLAIN sends the username and password in clear text (relying entirely on TLS for encryption), while SCRAM (SCRAM-SHA-256 or SCRAM-SHA-512) uses a challenge-response mechanism that never transmits the password itself, even over an unencrypted channel. For production, SCRAM is the safer default, but PLAIN is simpler for internal networks where TLS is mandatory. This article explains both mechanisms, how to configure them with TLS in Kafka, and how to decide which fits your use case.

Background: Kafka’s SASL Authentication Options

Apache Kafka uses SASL (Simple Authentication and Security Layer) to plug in different authentication mechanisms. The two most common for username/password setups are:

  • SASL/PLAIN – A simple mechanism that sends the username and password as a plaintext string inside the SASL exchange. It is defined in RFC 4616 and is the easiest to configure.
  • SASL/SCRAM – Short for Salted Challenge Response Authentication Mechanism (RFC 5802). It uses a salted password hash and a challenge-response handshake, so the password never crosses the wire. Kafka supports SCRAM-SHA-256 and SCRAM-SHA-512.

Both are used with a JAAS (Java Authentication and Authorization Service) configuration, either in a JAAS file or directly in the Kafka server properties. TLS (SSL) is typically enabled separately to encrypt the connection between clients and brokers. The choice of SASL mechanism is independent of TLS; you can use either with or without TLS, but best practice is to always use TLS in production.

How SASL/PLAIN Works

With SASL/PLAIN, the client sends a message containing the username and password in clear text (base64 encoded, but not encrypted). The broker then checks these credentials against its configured store (often a simple properties file or an external LDAP). Because the credentials are sent in the clear, SASL/PLAIN must be used over TLS to prevent eavesdropping. If you run Kafka without TLS, anyone on the network can sniff the password.

Configuration is straightforward. In the broker’s server.properties, you set:

listeners=SASL_SSL://0.0.0.0:9093
sasl.enabled.mechanisms=PLAIN
sasl.mechanism.inter.broker.protocol=PLAIN

Then create a JAAS file (e.g., kafka_server_jaas.conf) with:

KafkaServer {
  org.apache.kafka.common.security.plain.PlainLoginModule required
  username="admin"
  password="admin-secret"
  user_admin="admin-secret"
  user_alice="alice-secret";
};

Here, user_admin and user_alice define the credentials for each user. The broker’s own username/password (admin/admin-secret) are used for inter-broker communication.

How SASL/SCRAM Works

SCRAM avoids sending the password by using a challenge-response protocol. The broker stores a salted hash of the password (for example, SCRAM-SHA-256). When a client connects, the following happens:

  1. Client sends its username and a random nonce.
  2. Server responds with its own nonce, the salt, and the iteration count (default 4096 in Kafka).
  3. Client computes a proof using the password and salt, and sends it.
  4. Server verifies the proof and sends its own proof back to authenticate the server to the client.

This way, the password itself is never transmitted. Even if TLS is not used, the password is not exposed (though the channel is still vulnerable to tampering, so TLS is still recommended).

To configure SCRAM, first create credentials using the kafka-configs.sh tool. For example, to create a user alice with SCRAM-SHA-256:

bin/kafka-configs.sh --bootstrap-server localhost:9093 --alter --add-config 'SCRAM-SHA-256=[iterations=4096,password=alice-secret]' --entity-type users --entity-name alice

Then in server.properties:

sasl.enabled.mechanisms=SCRAM-SHA-256
sasl.mechanism.inter.broker.protocol=SCRAM-SHA-256

And in the JAAS file:

KafkaServer {
  org.apache.kafka.common.security.scram.ScramLoginModule required
  username="admin"
  password="admin-secret";
};

Note that SCRAM does not store user credentials in the JAAS file; it uses the ZooKeeper (or KRaft metadata) as the credential store. The JAAS file only contains the broker’s own credentials for inter-broker communication.

Configuring TLS with SASL

To use TLS with either mechanism, you set the listener to SASL_SSL and provide a keystore and truststore. Here’s a minimal broker configuration:

listeners=SASL_SSL://0.0.0.0:9093
ssl.keystore.location=/path/to/kafka.keystore.jks
ssl.keystore.password=keystore-password
ssl.key.password=key-password
ssl.truststore.location=/path/to/kafka.truststore.jks
ssl.truststore.password=truststore-password
ssl.client.auth=required

On the client side, you need a truststore that trusts the broker’s certificate, and optionally a keystore if client authentication is required. The client properties would look like:

security.protocol=SASL_SSL
sasl.mechanism=SCRAM-SHA-256
ssl.truststore.location=/path/to/client.truststore.jks
ssl.truststore.password=truststore-password

If you set ssl.client.auth=required, the client must also present a certificate, which is a separate form of authentication (mTLS). You can combine mTLS with SASL, but that is often overkill; choose one or the other.

Choosing Between PLAIN and SCRAM

Here are the key factors to consider:

  • Security of credentials at rest: PLAIN stores passwords in plaintext in the JAAS file (or an external store). SCRAM stores only salted hashes, so a compromised broker file does not directly reveal passwords.
  • Transmission security: PLAIN sends the password in clear text, so TLS is mandatory. SCRAM is safe even without TLS, but you should still use TLS to protect against man-in-the-middle attacks.
  • Ease of management: PLAIN is simpler to set up; you just edit a file. SCRAM requires using kafka-configs.sh to create credentials, which is an extra step but allows dynamic user management without restarting brokers.
  • Interoperability: PLAIN is supported by all Kafka clients, but some older clients may not support SCRAM. Check your client library’s documentation.
  • Compliance: If your organization requires that passwords never be transmitted or stored in plaintext, SCRAM is the only choice.

For most production environments, SCRAM-SHA-256 is recommended because it provides better security without much extra complexity. PLAIN is acceptable for internal, trusted networks where TLS is enforced and where you need the simplest possible setup.

Common Problems and Misconceptions

“Can I use PLAIN without TLS?� Technically yes, but it is highly discouraged because the password is sent in cleartext. Any network sniffer can capture it. If you must use PLAIN without TLS, do it only in a completely isolated network.

“Does SCRAM protect against password guessing?� SCRAM uses a salted hash with iteration counts, which slows down brute-force attacks, but it does not prevent them if the attacker obtains the stored hash. Use strong passwords and consider enabling additional security like rate limiting.

“I get ‘Authentication failed’ with SCRAM – what’s wrong?â€� Often it’s because the user was not created with the correct mechanism (e.g., you created with SCRAM-SHA-256 but the client is using SCRAM-SHA-512). Also, ensure the broker’s sasl.enabled.mechanisms includes the one you are using.

“Can I mix PLAIN and SCRAM on the same broker?� Yes, you can enable both mechanisms in sasl.enabled.mechanisms, and clients can choose which to use. However, you must ensure the JAAS configuration supports both login modules.

Alternatives to SASL/PLAIN and SCRAM

Kafka also supports other SASL mechanisms:

  • GSSAPI (Kerberos) – Enterprise-grade, uses a KDC, common in large organizations.
  • OAUTHBEARER – For OAuth 2.0 tokens, useful in cloud-native environments.
  • mTLS (mutual TLS) – Not SASL, but uses client certificates for authentication; often simpler than managing passwords.

If you are starting fresh, consider whether you need SASL at all. mTLS alone can provide strong authentication and encryption, but it requires managing certificates for every client. SASL with SCRAM is a good middle ground: password-based but secure.

Frequently Asked Questions

Is SASL/PLAIN secure if I use TLS?

Yes, when TLS is enforced, the password is encrypted in transit, so PLAIN becomes secure against eavesdropping. However, the password is still stored in plaintext on the broker, so an attacker with access to the server files can read it. For that reason, SCRAM is still preferable if you want to protect credentials at rest.

Does SCRAM require TLS?

No, SCRAM does not transmit the password, so it is safe to use without TLS. However, without TLS, the connection is vulnerable to man-in-the-middle attacks that could alter the data being sent. Always use TLS for production to protect data integrity and confidentiality.

How do I migrate from PLAIN to SCRAM?

First, create SCRAM credentials for all users using kafka-configs.sh. Then update the broker’s sasl.enabled.mechanisms to include SCRAM, and update client configurations to use SCRAM. You can run both mechanisms during the transition, then disable PLAIN once all clients are updated.

What is the default iteration count for SCRAM in Kafka?

Kafka uses 4096 iterations by default for SCRAM-SHA-256 and SCRAM-SHA-512. This is a reasonable balance between security and performance. You can specify a different count when creating credentials, but be aware that higher counts increase CPU usage.

Can I use SCRAM with ZooKeeper-based Kafka?

Yes, SCRAM works with both ZooKeeper-based and KRaft (metadata) mode. In ZooKeeper mode, the credentials are stored in ZooKeeper; in KRaft, they are stored in the metadata log. The configuration steps are the same.

Why do I get ‘SASL authentication failed’ with PLAIN?

Common causes: the username or password is wrong, the JAAS file is not correctly referenced (e.g., missing -Djava.security.auth.login.config), or the user is not defined in the JAAS file. Double-check the JAAS file syntax and ensure the broker has read permissions to it.

Related

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.

More cards in this drawer

The whole Numbers and Powers drawer →