TLS proves the broker's identity; SASL proves the client's. Kafka 129 offers GSSAPI (Kerberos), PLAIN, SCRAM-SHA-256, SCRAM-SHA-512 and OAUTHBEARER (mTLS and OAuth). SCRAM (RFC 5802) works out of the box: the broker stores only a salt, an iteration count and two keys derived from the password, and the client proves it knows the password without sending it. Kafka keeps the credentials in the metadata log, accepts SHA-256 and SHA-512 with at least 4,096 iterations, and the handshake must still run inside TLS (SASL_SSL).
sasl.enabled.mechanisms=SCRAM-SHA-512
sasl.mechanism.inter.broker.protocol=SCRAM-SHA-512
listener.name.internal.scram-sha-512.sasl.jaas.config=\
org.apache.kafka.common.security.scram.ScramLoginModule required \
username="broker" password="${file:/certs/secrets.properties:broker.password}";
listener.name.external.scram-sha-512.sasl.jaas.config=\
org.apache.kafka.common.security.scram.ScramLoginModule required;On INTERNAL, the inter-broker listener, the broker logs in as user broker, its password read from a separate file by the FileConfigProvider (a config provider, enabled with config.providers=file). The broker must authenticate before anyone can create users, so the first credentials go in at format time: the container's start.sh runs kafka-storage.sh format with --add-scram "SCRAM-SHA-512=[name=broker,password=...]" and the same for admin. Later users are added live with kafka-configs.sh --alter --entity-type users --add-config 'SCRAM-SHA-512=[iterations=8192,password=...]' (Authorization with ACLs). Asked with --describe --entity-type users (listings/l0614_users.sh), the cluster shows that it keeps no password:
SCRAM credential configs for user-principal 'analytics' are SCRAM-SHA-512=iterations=8192 SCRAM credential configs for user-principal 'admin' are SCRAM-SHA-512=iterations=4096 SCRAM credential configs for user-principal 'producer' are SCRAM-SHA-512=iterations=8192 SCRAM credential configs for user-principal 'broker' are SCRAM-SHA-512=iterations=4096
A Java client or command-line tool sets security.protocol=SASL_SSL, sasl.mechanism=SCRAM-SHA-512 and a sasl.jaas.config naming ScramLoginModule with the user and password (secrets.sh writes admin.properties this way); librdkafka clients use sasl.username and sasl.password (Securing the Cluster).