백엔드 데이터 인프라 115편. Kafka SASL 인증 깊이 — SCRAM-SHA-512 (권장)·PLAIN·OAUTHBEARER·GSSAPI (Kerberos)·AWS_MSK_IAM 5가지 메커니즘의 정확한 차이, JAAS config 작성, SCRAM credential 관리, OAuth 토큰 갱신, 운영 권장 패턴까지 풀어쓴 학습 노트.
이 글은 백엔드 데이터 인프라 시리즈 130편 중 115편이에요. 114편 에서 SSL/TLS 를 잡았다면, 이번 115편은 Authentication 의 깊이 — SASL (Simple Authentication and Security Layer). SCRAM·PLAIN·OAuth·Kerberos 5가지 메커니즘.
SASL이 어렵게 느껴지는 이유
메커니즘이 5가지인데 각각 인프라가 달라요. 게다가 JAAS 라는 또 다른 framework 까지 알아야 합니다.
첫째는 JAAS config 의 문법이에요. Java 표준이긴 한데 형식이 낯섭니다.
둘째는 메커니즘마다 운영 방식이 다른 점. SCRAM 은 kafka-configs.sh 로 user 를 생성하고, Kerberos 는 KDC, OAuth 는 identity provider 가 필요합니다.
이 글에서 5가지 메커니즘과 JAAS, 운영 패턴까지 한 번에 정리해요.
JAAS (Java Authentication and Authorization Service) 기초
Java 표준 인증 프레임워크예요. Kafka SASL 도 JAAS 기반으로 동작합니다.
형식
ServiceName {
LoginModule required
option1=value1
option2=value2;
};
ServiceName 자리에는 KafkaClient (client) 또는 KafkaServer (broker) 가 들어가요.
두 가지 설정 방식
Option 1: Java property file
# /etc/kafka/jaas.conf
KafkaClient {
org.apache.kafka.common.security.scram.ScramLoginModule required
username="alice"
password="password123";
};
$ export KAFKA_OPTS="-Djava.security.auth.login.config=/etc/kafka/jaas.conf"
Option 2: sasl.jaas.config (인라인)
sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required \
username="alice" \
password="password123";
Option 2 인라인 방식을 권장해요. Spring Boot 나 환경별 별도 설정에서 더 자연스럽거든요.
1. SASL/PLAIN — 단순 username/password
sasl.mechanism=PLAIN
sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required \
username="alice" \
password="password123";
특징
- 가장 단순
- 평문 전송 → 반드시 SSL 위에서 (SASL_SSL)
- broker 측 credential 저장 필요 → JAAS 또는 외부 파일
Broker 측
sasl.enabled.mechanisms=PLAIN
sasl.mechanism.inter.broker.protocol=PLAIN
# JAAS 에 user 정의 (모든 user 명시)
listener.name.sasl_ssl.plain.sasl.jaas.config=\
org.apache.kafka.common.security.plain.PlainLoginModule required \
username="admin" \
password="admin-pass" \
user_admin="admin-pass" \
user_alice="alice-pass" \
user_bob="bob-pass";
user_<name>="password" 형식으로 각 user 를 정의해요.
여기서 시험 함정이 하나 있어요 — 모든 user 가 JAAS config 에 평문으로 들어간다는 점. 운영 환경에서는 매우 위험하니 SCRAM (Salted Challenge Response Authentication Mechanism) 을 권장합니다.
2. SASL/SCRAM-SHA-256 / SCRAM-SHA-512 — 운영 표준
특징
- Challenge-response (평문 비밀번호 안 보냄)
- broker 측 salted hash 저장 (평문 X)
- kafka-configs.sh 로 user 동적 관리
- SHA-512 권장 (SHA-256 보다 강력)
Broker 측 활성
sasl.enabled.mechanisms=SCRAM-SHA-512
sasl.mechanism.inter.broker.protocol=SCRAM-SHA-512
# inter-broker 용 user JAAS
listener.name.sasl_ssl.scram-sha-512.sasl.jaas.config=\
org.apache.kafka.common.security.scram.ScramLoginModule required \
username="admin" \
password="admin-pass";
User Credential 생성
$ kafka-configs.sh --bootstrap-server localhost:9092 \
--alter --add-config 'SCRAM-SHA-512=[iterations=8192,password=alice-pass]' \
--entity-type users --entity-name alice
ACL (Access Control List) 환경에서는 admin 권한이 필요해요.
Client 측
security.protocol=SASL_SSL
sasl.mechanism=SCRAM-SHA-512
sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required \
username="alice" \
password="alice-pass";
User 관리
# 목록
$ kafka-configs.sh --bootstrap-server localhost:9092 \
--describe --entity-type users
# 변경
$ kafka-configs.sh --bootstrap-server localhost:9092 \
--alter --add-config 'SCRAM-SHA-512=[password=new-pass]' \
--entity-type users --entity-name alice
# 삭제
$ kafka-configs.sh --bootstrap-server localhost:9092 \
--alter --delete-config 'SCRAM-SHA-512' \
--entity-type users --entity-name alice
KRaft (Kafka Raft, ZooKeeper 없는 모드) 환경이면 모든 broker 가 새 credential 을 즉시 인식해요. 옛 ZK 모드는 ZooKeeper 에 저장됩니다.
3. SASL/GSSAPI — Kerberos
특징
- 대기업의 기존 Kerberos 인프라 (AD·MIT Kerberos) 활용
- 매우 강력하지만 복잡
- Keytab 파일로 credential 표현
Broker 측
sasl.enabled.mechanisms=GSSAPI
sasl.mechanism.inter.broker.protocol=GSSAPI
sasl.kerberos.service.name=kafka
listener.name.sasl_ssl.gssapi.sasl.jaas.config=\
com.sun.security.auth.module.Krb5LoginModule required \
useKeyTab=true \
storeKey=true \
keyTab="/etc/security/keytabs/kafka_broker.keytab" \
principal="kafka/broker-1.example.com@EXAMPLE.COM";
Client 측
security.protocol=SASL_SSL
sasl.mechanism=GSSAPI
sasl.kerberos.service.name=kafka
sasl.jaas.config=com.sun.security.auth.module.Krb5LoginModule required \
useKeyTab=true \
storeKey=true \
keyTab="/etc/security/keytabs/alice.keytab" \
principal="alice@EXAMPLE.COM";
운영 부담
- KDC (Key Distribution Center) 운영
- Keytab 파일 보관·rotation
- Ticket 갱신
- Time sync 필수 (NTP)
복잡해서 새 환경이면 보통 SCRAM 이나 OAuth 를 선호해요.
4. SASL/OAUTHBEARER — OAuth 2.0
특징
- OAuth 2.0 / OpenID Connect 통합
- cloud + SSO 환경 표준
- Token 기반 (단기 토큰 자동 갱신)
- Confluent Cloud·Aiven·MSK 등 cloud 표준
Broker 측
sasl.enabled.mechanisms=OAUTHBEARER
sasl.mechanism.inter.broker.protocol=OAUTHBEARER
# OAuth provider 통합
listener.name.sasl_ssl.oauthbearer.sasl.jaas.config=\
org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required;
listener.name.sasl_ssl.oauthbearer.sasl.server.callback.handler.class=\
com.example.MyOAuthValidatorCallbackHandler
Custom callback handler 가 token 검증 로직을 provider 별로 구현해요.
Client 측
security.protocol=SASL_SSL
sasl.mechanism=OAUTHBEARER
sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \
oauth.token.endpoint.uri="https://auth.example.com/oauth2/token" \
oauth.client.id="kafka-app" \
oauth.client.secret="..." \
oauth.scope="kafka.access";
sasl.login.callback.handler.class=\
org.apache.kafka.common.security.oauthbearer.secured.OAuthBearerLoginCallbackHandler
토큰 갱신
sasl.login.refresh.window.factor=0.8 # token 수명의 80% 시점에 갱신
sasl.login.refresh.window.jitter=0.05
sasl.login.refresh.min.period.seconds=60
sasl.login.refresh.buffer.seconds=300
자동 토큰 갱신이라 재시작 없이 운영할 수 있어요.
5. SASL/AWS_MSK_IAM — AWS 전용
특징
- AWS MSK (Managed Streaming for Kafka) 전용
- IAM (Identity and Access Management) role 기반 (Kafka credential 없음)
- IAM policy 로 권한 관리
Client 측
security.protocol=SASL_SSL
sasl.mechanism=AWS_MSK_IAM
sasl.jaas.config=software.amazon.msk.auth.iam.IAMLoginModule required;
sasl.client.callback.handler.class=software.amazon.msk.auth.iam.IAMClientCallbackHandler
EC2 의 instance profile 이나 AWS SDK credential chain 을 자동으로 활용해요.
장점:
- Kafka credential 관리 불필요
- IAM 통합 (이미 있는 권한 관리)
- AWS 환경 최적
단점:
- AWS lock-in
- non-AWS client 사용 어려움
Inter-Broker SASL
security.inter.broker.protocol=SASL_SSL
sasl.mechanism.inter.broker.protocol=SCRAM-SHA-512
Inter-broker 통신도 반드시 보안으로 가져가야 해요. 별도 admin user 를 씁니다.
Spring Boot 통합
SCRAM
spring:
kafka:
bootstrap-servers: broker-1.example.com:9093
properties:
security.protocol: SASL_SSL
sasl.mechanism: SCRAM-SHA-512
sasl.jaas.config: >
org.apache.kafka.common.security.scram.ScramLoginModule required
username="${KAFKA_USERNAME}"
password="${KAFKA_PASSWORD}";
ssl.truststore.location: /etc/kafka/ssl/truststore.jks
ssl.truststore.password: ${TRUSTSTORE_PASSWORD}
환경변수로 password 를 주입하면 코드나 git 에 password 가 박히지 않아요.
OAuth
spring:
kafka:
properties:
sasl.mechanism: OAUTHBEARER
sasl.jaas.config: >
org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required
oauth.token.endpoint.uri="${OAUTH_TOKEN_URL}"
oauth.client.id="${OAUTH_CLIENT_ID}"
oauth.client.secret="${OAUTH_CLIENT_SECRET}"
oauth.scope="kafka.access";
sasl.login.callback.handler.class: org.apache.kafka.common.security.oauthbearer.secured.OAuthBearerLoginCallbackHandler
선택 가이드 (다시)
| 환경 | 권장 |
|---|---|
| 학습·개발 | PLAIN (SASL_PLAINTEXT) |
| 일반 운영 | SCRAM-SHA-512 (SASL_SSL) |
| 대기업 + AD | GSSAPI (SASL_SSL) |
| Cloud + SSO | OAUTHBEARER (SASL_SSL) |
| AWS MSK | AWS_MSK_IAM |
한계·실무 함정
1. PLAIN 운영 환경
위에서 강조했듯 평문에 JAAS 평문 저장이라 SCRAM 을 권장해요.
2. JAAS config 의 password
평문 저장은 위험해요. 환경변수와 Kubernetes Secret·Vault 같은 secret manager 를 씁니다.
3. SCRAM credential ZK 모드
옛 ZK 모드는 ZooKeeper 에 저장돼서 ZK 도 보안이 필요해요. KRaft 를 권장합니다.
4. Kerberos time sync
KDC·broker·client 의 시계가 동기화되지 않으면 ticket validation 이 실패해요. NTP 가 필수입니다.
5. OAuth 토큰 만료
자동 갱신이 안 되면 모든 client 인증이 실패해요. callback handler 를 검증해야 합니다.
6. Inter-broker SASL 누락
security.inter.broker.protocol=PLAINTEXT 로 두면 inter-broker 가 평문 인증이 안 돼요. 운영에서는 필수로 잡아둡니다.
시험 직전 한 번 더 — Kafka SASL 함정 압축 노트
- JAAS = Java 표준 인증 프레임워크
- 형식 =
ServiceName { LoginModule required option=value; }; - 두 가지 = java property file 또는
sasl.jaas.config인라인 (권장) - 5가지 메커니즘 = PLAIN · SCRAM-SHA-256/512 (권장) · GSSAPI (Kerberos) · OAUTHBEARER · AWS_MSK_IAM
- PLAIN = 단순, 평문, 운영 비권장
- SCRAM = challenge-response, salted hash, 동적 user 관리, 운영 표준
- GSSAPI = 대기업 Kerberos, 복잡, KDC·Keytab
- OAUTHBEARER = OAuth 2.0, cloud + SSO 표준
- AWS_MSK_IAM = AWS MSK 전용, IAM role
- SCRAM credential =
kafka-configs.sh --alter --add-config 'SCRAM-SHA-512=[iterations=8192,password=...]' --entity-type users - KRaft 환경 = 모든 broker 즉시 인식
- OAuth 토큰 자동 갱신 =
sasl.login.refresh.* - Inter-broker SASL =
security.inter.broker.protocol=SASL_SSL - Spring Boot =
sasl.jaas.config에 환경변수 주입 (password 안 박음) - 함정 — PLAIN 운영 (JAAS 평문 저장)
- 함정 — JAAS config password 평문 → secret manager
- 함정 — Kerberos time sync (NTP)
- 함정 — OAuth 토큰 갱신 실패
- 함정 — Inter-broker SASL 누락
- 함정 — SCRAM credential ZK 모드 (KRaft 권장)
공식 문서: Kafka Security SASL 에서 자세한 사양과 예제를 확인할 수 있어요.
시리즈 다른 편 (앞뒤 글 모음)
이전 글:
- 110편 — Kafka Message Format (Record Batch v2 · 바이트 구조)
- 111편 — Kafka Consumer Rebalance Protocol (KIP-848 새 모델)
- 112편 — Kafka Transaction Protocol (EOS 내부 메커니즘)
- 113편 — Kafka Security Overview (3축 종합)
- 114편 — Kafka SSL/TLS (Keystore · mTLS · 인증서 운영)
다음 글: