백엔드 데이터 인프라 115편 — Kafka SASL (SCRAM · PLAIN · OAuth · Kerberos)

2026-05-17백엔드 데이터 인프라

백엔드 데이터 인프라 115편. Kafka SASL 인증 깊이 — SCRAM-SHA-512 (권장)·PLAIN·OAUTHBEARER·GSSAPI (Kerberos)·AWS_MSK_IAM 5가지 메커니즘의 정확한 차이, JAAS config 작성, SCRAM credential 관리, OAuth 토큰 갱신, 운영 권장 패턴까지 풀어쓴 학습 노트.

📚 백엔드 데이터 인프라 · 115편 — Kafka SASL (SCRAM · PLAIN · OAuth · Kerberos)

이 글은 백엔드 데이터 인프라 시리즈 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 에서 자세한 사양과 예제를 확인할 수 있어요.

시리즈 다른 편 (앞뒤 글 모음)

이전 글:

다음 글:

※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

답글 남기기

error: Content is protected !!