Kafka Consumer
SASL Mechanism
Security Protocol
SASL_SSL
Java Configuration

How to configure kafka consumer with sasl mechanism PLAIN and with security protocol SASL_SSL in java?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

A Kafka consumer using SASL_SSL with the PLAIN mechanism authenticates with a username and password while also encrypting the network connection with TLS. In practice, most failures come from mixing broker settings, JAAS configuration, and truststore settings rather than from the poll loop itself.

The consumer only needs a small set of security properties, but they must agree with what the brokers expose. If one side says SASL_SSL and the other side expects plain SSL or plain SASL_PLAINTEXT, the handshake will fail immediately.

The Core Client Properties

A Java consumer needs the normal Kafka settings plus the security-specific ones:

  • 'bootstrap.servers'
  • 'group.id'
  • deserializers
  • 'security.protocol=SASL_SSL'
  • 'sasl.mechanism=PLAIN'
  • a JAAS login configuration
  • truststore settings so the client can trust the broker certificate

A minimal runnable example looks like this:

java
1import org.apache.kafka.clients.consumer.ConsumerConfig;
2import org.apache.kafka.clients.consumer.ConsumerRecords;
3import org.apache.kafka.clients.consumer.KafkaConsumer;
4import org.apache.kafka.common.serialization.StringDeserializer;
5
6import java.time.Duration;
7import java.util.Collections;
8import java.util.Properties;
9
10public class SecureKafkaConsumer {
11    public static void main(String[] args) {
12        Properties props = new Properties();
13        props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "broker1.example.com:9093");
14        props.put(ConsumerConfig.GROUP_ID_CONFIG, "secure-demo-group");
15        props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
16        props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
17        props.put("security.protocol", "SASL_SSL");
18        props.put("sasl.mechanism", "PLAIN");
19        props.put(
20            "sasl.jaas.config",
21            "org.apache.kafka.common.security.plain.PlainLoginModule required " +
22            "username=\"app-user\" password=\"app-password\";"
23        );
24        props.put("ssl.truststore.location", "/opt/app/certs/kafka.truststore.jks");
25        props.put("ssl.truststore.password", "changeit");
26
27        try (KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props)) {
28            consumer.subscribe(Collections.singletonList("orders"));
29
30            while (true) {
31                ConsumerRecords<String, String> records = consumer.poll(Duration.ofSeconds(1));
32                records.forEach(record ->
33                    System.out.printf("partition=%d offset=%d value=%s%n",
34                        record.partition(), record.offset(), record.value())
35                );
36            }
37        }
38    }
39}

If your organization provides a separate JAAS file, you can use the JVM option -Djava.security.auth.login.config=/path/to/jaas.conf instead of the inline sasl.jaas.config property.

What the Broker Must Expose

The client configuration only works if the broker listener is configured for the same security protocol and mechanism. Conceptually, the broker must:

  • listen on a SASL_SSL endpoint
  • enable the PLAIN mechanism
  • have TLS certificates configured
  • recognize the client credentials through the configured authentication backend

The exact broker settings vary by deployment, but the important point is alignment. Client and broker settings are a contract.

Truststore and Certificate Validation

SASL_SSL uses TLS under the authentication layer. That means the consumer must trust the certificate chain presented by the Kafka broker.

If the broker certificate is signed by a private CA, import that CA certificate into the truststore referenced by ssl.truststore.location. Without that, the consumer may fail before it even gets to SASL authentication.

In many environments, hostname verification is also enabled. That means the broker hostname in bootstrap.servers must match the certificate subject or subject alternative name entries.

Inline JAAS Versus External JAAS File

Both styles are valid.

Inline JAAS in Properties is convenient for containerized deployments because everything stays in one config object. An external JAAS file is useful when your platform already manages JVM startup flags centrally.

The main rule is consistency. Do not set one username in the JAAS file and a different one in copied sample code. Debugging becomes confusing because the failure looks like a generic authentication problem.

Common Pitfalls

  • Setting security.protocol to SSL instead of SASL_SSL. TLS alone does not enable SASL authentication.
  • Forgetting sasl.jaas.config or pointing to the wrong JAAS file. Without credentials, the PLAIN login cannot start.
  • Using a truststore that does not contain the broker CA certificate. The TLS handshake fails before the consumer can authenticate.
  • Connecting to broker:9092 while the secure listener is actually exposed on another port such as 9093.
  • Mixing client and broker expectations, such as enabling SCRAM on the broker while the client still sends PLAIN.

Summary

  • A secure Java consumer needs both SASL settings and TLS trust settings.
  • The essential client properties are security.protocol=SASL_SSL, sasl.mechanism=PLAIN, JAAS credentials, and a valid truststore.
  • Broker and client settings must describe the same listener and the same mechanism.
  • TLS certificate trust is a separate requirement from SASL authentication.
  • Most connection errors come from config mismatch, not from the consumer loop itself.

Course illustration
Course illustration

All Rights Reserved.