JAAS configuration
Kafka
Kubernetes
environment variables
Kubernetes deployment

How to pass JAAS configuration kafka env variables kubernetes

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

Passing Kafka JAAS settings through Kubernetes usually works best when you separate secrets from startup flags. Instead of embedding a long multi-line JAAS block directly into an environment variable, mount the JAAS file from a Kubernetes Secret and use an env var such as KAFKA_OPTS to point the JVM at that file.

The reliable pattern: secret plus JVM option

Kafka clients and brokers typically read JAAS config through the JVM system property java.security.auth.login.config. In Kubernetes, that maps cleanly to:

  1. store the JAAS file in a Secret
  2. mount the secret into the container filesystem
  3. set KAFKA_OPTS so the Java process reads the mounted file

Example secret:

yaml
1apiVersion: v1
2kind: Secret
3metadata:
4  name: kafka-jaas
5type: Opaque
6stringData:
7  client-jaas.conf: |
8    KafkaClient {
9      org.apache.kafka.common.security.plain.PlainLoginModule required
10      username="app-user"
11      password="app-password";
12    };

Example deployment:

yaml
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4  name: kafka-client
5spec:
6  replicas: 1
7  selector:
8    matchLabels:
9      app: kafka-client
10  template:
11    metadata:
12      labels:
13        app: kafka-client
14    spec:
15      containers:
16        - name: app
17          image: ghcr.io/example/kafka-client:1.0.0
18          env:
19            - name: KAFKA_OPTS
20              value: "-Djava.security.auth.login.config=/etc/kafka/jaas/client-jaas.conf"
21          volumeMounts:
22            - name: jaas
23              mountPath: /etc/kafka/jaas
24              readOnly: true
25      volumes:
26        - name: jaas
27          secret:
28            secretName: kafka-jaas

This pattern works across many Java-based Kafka clients because it relies on the standard JVM property instead of image-specific parsing rules.

When environment variables alone are required

Some container images expose their own variables for SASL username, password, and mechanism. Others do not. If your image insists on env-only input, a common compromise is:

  1. inject the username and password from a Secret as environment variables
  2. write the JAAS file in the container entrypoint
  3. start the Java process with KAFKA_OPTS

Example startup script:

bash
1cat >/tmp/client-jaas.conf <<EOF
2KafkaClient {
3  org.apache.kafka.common.security.plain.PlainLoginModule required
4  username="${KAFKA_USERNAME}"
5  password="${KAFKA_PASSWORD}";
6};
7EOF
8
9export KAFKA_OPTS="-Djava.security.auth.login.config=/tmp/client-jaas.conf"
10exec java -jar app.jar

This still avoids hard-coding credentials into the image.

Do not forget the rest of the Kafka security config

JAAS alone is not enough. Your client also needs the matching Kafka properties, usually through application config or environment variables:

properties
security.protocol=SASL_SSL
sasl.mechanism=PLAIN

If these do not match the broker configuration, the JAAS file can be correct and authentication will still fail.

Why mounted files are usually better than raw env vars

Mounted JAAS files are easier to:

  • rotate through Kubernetes secret updates
  • inspect in a running pod during debugging
  • reuse across multiple Java processes
  • keep readable when the JAAS stanza becomes long

A single quoted env var can work, but it becomes brittle fast, especially once escaping and line breaks enter the picture.

One more operational detail matters: most Java applications do not automatically reload JAAS files when a Kubernetes secret changes. Secret rotation usually still requires a pod restart unless your application has explicit reload support.

Common Pitfalls

  • Putting the JAAS text in an env var but never wiring KAFKA_OPTS to java.security.auth.login.config.
  • Assuming every Kafka container image understands the same environment variables.
  • Forgetting to set security.protocol and sasl.mechanism alongside the JAAS config.
  • Storing plaintext credentials directly in a deployment manifest instead of a Kubernetes Secret.
  • Writing a JAAS file at startup but forgetting to exec the Java process with the updated environment.

Summary

  • The most reliable Kubernetes pattern is a JAAS file in a Secret plus KAFKA_OPTS.
  • Mount the secret into the container and point java.security.auth.login.config at it.
  • Use env-only generation only when the image or platform forces that approach.
  • Keep the rest of the Kafka SASL settings aligned with the JAAS file.
  • Prefer secret-backed configuration over long inline credential strings in manifests.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.