백엔드 데이터 인프라 116편 — Kafka ACL (Authorization 깊이)

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

백엔드 데이터 인프라 116편. Kafka ACL Authorization 깊이 — Principal · Operation · Resource 3 tuple, kafka-acls.sh 명령, LITERAL · PREFIXED · MATCH resource pattern, super.users, team 별 권한 분리 패턴, StandardAuthorizer vs Custom 까지 풀어쓴 학습 노트. Part 5-8 Security 마무리.

📚 백엔드 데이터 인프라 · 116편 — Kafka ACL (Authorization 깊이)

이 글은 백엔드 데이터 인프라 시리즈 130편 중 116편이에요. Part 5-8 Security 의 마지막 글. 113~115편 으로 Authentication·Encryption 을 잡았다면, 이번 116편은 Authorization — ACL(접근 제어 목록) 깊이.

ACL이 어렵게 느껴지는 이유

3 tuple (Principal · Operation · Resource) 조합에 resource pattern 까지 더하면 가능한 경우의 수가 한 번에 부푼다.

먼저 resource 타입 5가지에 operation 8가지가 곱해져 40개 조합이 나오는데, 그중 자주 쓰이는 게 어떤 건지 감이 잘 안 잡힌다. 여기에 Pattern 3가지 (LITERAL·PREFIXED·MATCH) 가 또 붙어 조합이 3배로 늘어난다. 마지막 함정이 allow.everyone.if.no.acl.found — 기본값은 false 지만 true 로 두는 순간 ACL 자체가 의미를 잃는다.

이 글에서 3 tuple, pattern, 운영 패턴까지 한 번에 짚는다.

ACL 의 3 tuple

ACL = (Principal, Operation, Resource)

읽는 법은 단순하다. "Principal 이 Resource 에 대해 Operation 을 할 수 있다".

여기에 추가 옵션이 세 개 붙는다. Permission Type 은 ALLOW (기본) 또는 DENY, Host 는 특정 IP 만 받거나 기본값 * 로 전부 열어두고, Resource Pattern Type 으로 LITERAL · PREFIXED · MATCH 중 하나를 고른다.

Principal — 누구

User:alice                       # 일반 user
User:CN=alice,OU=Eng,O=...       # X.509 DN (mTLS)
User:ANONYMOUS                   # 인증 안 한 user

SASL/SCRAM 이면 User:<username> 형태, SSL/mTLS(양방향 TLS 인증) 이면 User:<dn> 또는 ssl.principal.mapping.rules 로 매핑해서 쓴다.

Operation — 무엇

Operation Resource 설명
Read Topic, Group 메시지 read, group offset commit
Write Topic, TransactionalId 메시지 write, transaction commit
Create Topic, Cluster Topic 생성
Delete Topic Topic 삭제
Alter Topic, Cluster Config 변경, partition 추가
Describe Topic, Group, Cluster, TransactionalId Metadata 조회
ClusterAction Cluster Inter-broker (replica fetch 등)
DescribeConfigs Topic, Broker Config 조회
AlterConfigs Topic, Broker Config 변경
IdempotentWrite Cluster Idempotent producer
All Any 모든 operation

대부분의 application 이 결국 쓰는 건 Read · Write · Describe 세 개로 좁혀진다.

Resource Type 5가지

Type 예제
Topic orders, payments, events.*
Group order-workers, analytics-*
Cluster kafka-cluster (cluster-wide ops)
TransactionalId tx-1, payment-tx-* (transactional producer)
DelegationToken delegation token (분산 인증)

Resource Pattern — 3가지

LITERAL — 정확 일치

--topic orders --resource-pattern-type LITERAL

정확히 orders topic 하나에만 매칭된다.

PREFIXED — 접두사 일치

--topic prod.order-team. --resource-pattern-type PREFIXED

prod.order-team.* 로 시작하는 모든 topic 에 한 번에 권한이 붙는다. 101편 multi-tenancy 에서 본 패턴이고, 새 topic 이 추가돼도 ACL 을 다시 박을 필요가 없다는 게 가장 큰 장점.

MATCH — 모든 일치 (조회용)

--topic '*' --resource-pattern-type MATCH

ACL 조회할 때만 쓴다. 새 ACL 을 생성하는 용도로는 못 쓴다.

kafka-acls.sh — 명령

ACL 추가

$ kafka-acls.sh --bootstrap-server localhost:9092 \
    --add --allow-principal User:alice \
    --operation Read --operation Write \
    --topic orders

--operation 을 여러 번 붙이면 한 번에 여러 권한이 들어간다.

Consumer Group ACL

$ kafka-acls.sh --bootstrap-server localhost:9092 \
    --add --allow-principal User:alice \
    --operation Read --operation Describe \
    --group order-workers

Consumer 는 Topic Read 뿐 아니라 Group Read · Describe 까지 같이 박아야 동작한다.

PREFIXED

$ kafka-acls.sh --bootstrap-server localhost:9092 \
    --add --allow-principal User:order-team-app \
    --operation All \
    --topic 'prod.order-team.' --resource-pattern-type PREFIXED \
    --group 'prod.order-team.' --resource-pattern-type PREFIXED

Producer ACL

$ kafka-acls.sh --bootstrap-server localhost:9092 \
    --producer \
    --allow-principal User:alice \
    --topic orders

--producer 옵션은 Write + Describe + Create 를 Topic · TransactionalId · IdempotentWrite 에 자동으로 박아주는 편의 옵션.

Consumer ACL

$ kafka-acls.sh --bootstrap-server localhost:9092 \
    --consumer \
    --allow-principal User:alice \
    --topic orders \
    --group order-workers

--consumer 도 Topic 의 Read · Describe 와 Group 의 Read 를 자동으로 박는 편의 옵션이다.

조회

$ kafka-acls.sh --bootstrap-server localhost:9092 --list
$ kafka-acls.sh --bootstrap-server localhost:9092 --list --topic orders
$ kafka-acls.sh --bootstrap-server localhost:9092 --list --principal User:alice

삭제

$ kafka-acls.sh --bootstrap-server localhost:9092 \
    --remove --allow-principal User:alice \
    --topic orders --operation Read

Allow vs Deny 우선순위

1. 어떤 DENY ACL 이 매칭? → 거부
2. 어떤 ALLOW ACL 이 매칭? → 허용
3. 둘 다 없음 → allow.everyone.if.no.acl.found 따라

DENY 가 ALLOW 보다 우선이다. "전부 열어주되 특정 user 만 차단" 하는 패턴을 이 우선순위로 만든다.

# 모두 read OK
$ kafka-acls.sh --add --allow-principal User:* --operation Read --topic public

# 단 bob 만 차단
$ kafka-acls.sh --add --deny-principal User:bob --operation Read --topic public

super.users

# broker config
super.users=User:admin;User:CN=admin-cert

여기에 들어간 user 는 모든 ACL 검사를 건너뛴다. 사실상 무제한 권한이다.

운영 환경에서는 운영 admin 한 명 정도가 적당하고, 너무 많이 박으면 ACL 을 둔 의미 자체가 사라진다.

allow.everyone.if.no.acl.found

# broker config
allow.everyone.if.no.acl.found=false      # 기본

여기가 정말 중요한 자리다. false (기본·운영 권장) 면 ACL 이 없는 resource 는 전부 거부되고, true 면 ACL 없는 resource 가 전부 열린다 (insecure). 운영 환경은 반드시 false 로 두는데, 일부 환경 (Confluent) 은 기본이 true 라 시작하자마자 바꿔야 한다.

Authorizer — 구현체 선택

StandardAuthorizer (Kafka 3.3+ 권장)

# KRaft mode
authorizer.class.name=org.apache.kafka.metadata.authorizer.StandardAuthorizer

KRaft(ZooKeeper 없는 Kafka 합의 프로토콜) 환경의 표준. ACL 을 metadata log 에 저장한다.

AclAuthorizer (옛 ZK mode)

# ZK mode
authorizer.class.name=kafka.security.authorizer.AclAuthorizer

ZooKeeper 에 ACL 을 저장하던 옛 모드용.

Custom Authorizer

public class MyAuthorizer implements Authorizer {
    @Override
    public List<AuthorizationResult> authorize(...) {
        // 외부 시스템 (OPA·LDAP·DB) 조회
        // ...
    }
}
authorizer.class.name=com.example.MyAuthorizer

엔터프라이즈 환경에서 기존 권한 관리 시스템 — OPA(정책 엔진), LDAP(디렉터리 인증 프로토콜), 내부 DB — 와 통합할 때 쓴다.

운영 패턴 — Team 별 권한 분리 (101편 종합)

TEAM=order-team
ENV=prod

# 1. SASL user 생성 (115편)
$ kafka-configs.sh --bootstrap-server localhost:9092 \
    --alter --add-config 'SCRAM-SHA-512=[iterations=8192,password=...]' \
    --entity-type users --entity-name ${TEAM}-app

# 2. Topic ACL (PREFIXED)
$ kafka-acls.sh --bootstrap-server localhost:9092 \
    --add --allow-principal User:${TEAM}-app \
    --operation All \
    --topic "${ENV}.${TEAM}." --resource-pattern-type PREFIXED

# 3. Group ACL (PREFIXED)
$ kafka-acls.sh --bootstrap-server localhost:9092 \
    --add --allow-principal User:${TEAM}-app \
    --operation All \
    --group "${ENV}.${TEAM}." --resource-pattern-type PREFIXED

# 4. Quota (101편)
$ kafka-configs.sh --bootstrap-server localhost:9092 \
    --alter --add-config 'producer_byte_rate=20971520,consumer_byte_rate=20971520' \
    --entity-type users --entity-name ${TEAM}-app

이 흐름을 자동화 스크립트로 묶어두면 team onboarding 표준이 된다.

자주 헷갈리는 ACL 조합

Consumer 필수 ACL

- Topic Read on orders
- Topic Describe on orders
- Group Read on order-workers
- Group Describe on order-workers

--consumer 옵션이 이 네 가지를 자동으로 박아준다.

Producer 필수 ACL

- Topic Write on orders
- Topic Describe on orders
- (transactional) TransactionalId Write on tx-id
- (idempotent) Cluster IdempotentWrite

--producer 옵션이 자동으로 박아준다.

Admin 필수 ACL

- Cluster Create / Describe / Alter
- Topic Create / Delete / Alter / DescribeConfigs / AlterConfigs
- Group Describe / Delete

이 정도면 그냥 super.users 로 넣는 쪽이 낫다.

모니터링

JMX(자바 모니터링 표준) 로 세 가지를 본다.

  • authorize-time-ns — ACL 검사 시간
  • failed-authorization-rate — 실패율
  • cache-hit-rate — ACL cache 효율

failed-authorization-rate 가 높게 튄다면 설정이 잘못됐거나 공격 시도가 들어오고 있다는 신호다.

한계·실무 함정

1. allow.everyone.if.no.acl.found=true

가장 위험한 설정. ACL 을 둔 의미가 통째로 사라지니까 반드시 false 로 둔다.

2. super.users 남발

너무 많이 넣으면 ACL 자체가 무의미해진다. 최소 1~2 명으로 유지한다.

3. PREFIXED 누락

새 topic 이 늘어날 때 LITERAL ACL 만 박아두면 매번 ACL 을 추가해야 한다. 운영 표준은 PREFIXED 다.

4. Group ACL 누락

Consumer 에 Topic Read 만 박고 Group Read 를 빼먹으면 consumer group commit 단계에서 실패가 난다.

5. mTLS Principal 매핑 오류

ssl.principal.mapping.rules 가 어긋나면 principal 이름이 달라져서 ACL match 가 안 된다.

6. Custom Authorizer 의 latency

ACL 검사는 모든 request 마다 일어나는 일이라 custom authorizer 가 느리면 전체 throughput 이 같이 떨어진다. caching 이 필수.

Part 5-8 Security 마무리

4편 (113~116):

  • 113 Security Overview — 3축 종합 + protocol 4가지
  • 114 SSL/TLS — Keystore·Truststore·mTLS·인증서 운영
  • 115 SASL — 5가지 메커니즘·JAAS·SCRAM 운영
  • 116 ACL — 3 tuple·PREFIXED·super.users·team 패턴

Kafka 보안은 결국 조합 문제다. SASL_SSL + SCRAM-SHA-512 + StandardAuthorizer + ACL PREFIXED 가 운영 황금 조합.

시험 직전 한 번 더 — Kafka ACL 함정 압축 노트

  • ACL = (Principal, Operation, Resource) 3 tuple + Permission Type + Host + Pattern
  • Principal = User:<name> (SASL) 또는 User:<DN> (mTLS)
  • Operation 자주 = Read · Write · Describe + Create · Delete · Alter
  • Resource Type 5가지 = Topic · Group · Cluster · TransactionalId · DelegationToken
  • Resource Pattern 3가지 = LITERAL (정확) · PREFIXED (접두사) · MATCH (조회만)
  • PREFIXED = 운영 표준 (새 topic 자동 권한)
  • kafka-acls.sh--add·--remove·--list + --allow-principal / --deny-principal
  • --producer = Write + Describe + Topic Create + TransactionalId + IdempotentWrite 자동
  • --consumer = Topic Read + Describe + Group Read 자동
  • Allow vs Deny — DENY 가 우선
  • super.users=User:admin = ACL 검사 skip (최소만)
  • allow.everyone.if.no.acl.found=false (기본·운영 권장) — true = ACL 의미 X
  • Authorizer 구현체StandardAuthorizer (KRaft, Kafka 3.3+) / AclAuthorizer (ZK) / Custom
  • Team 별 권한 분리 = SASL user + PREFIXED Topic ACL + PREFIXED Group ACL + Quota
  • 자동화 스크립트 = team onboarding 표준
  • 모니터링 = failed-authorization-rate·cache-hit-rate
  • 함정 — allow.everyone.if.no.acl.found=true 가장 위험
  • 함정 — super.users 남발
  • 함정 — PREFIXED 누락 → 매번 ACL 추가
  • 함정 — Group ACL 누락 → commit 실패
  • 함정 — mTLS Principal 매핑 오류
  • 함정 — Custom Authorizer latency → caching 필수
  • Part 5-8 Security 4편 = Overview·SSL·SASL·ACL
  • 운영 황금 조합 = SASL_SSL + SCRAM-SHA-512 + StandardAuthorizer + PREFIXED ACL

공식 문서: Kafka Authorization and ACLs 에서 자세한 사양을 확인할 수 있어요.

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

이전 글:

다음 글:

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

답글 남기기

error: Content is protected !!