一、授权框架概览:开启可插拔 Authorizer
Kafka 内置可插拔的授权框架,通过 authorizer.class.name 指定 Authorizer 实现。被配置实现需继承 org.apache.kafka.server.authorizer.Authorizer。
KRaft 模式下,Kafka 提供默认实现,将 ACL 存储在 集群元数据(KRaft 元数据日志) 中。请在 所有节点(broker、controller 或二者合一)设置:
properties
authorizer.class.name=org.apache.kafka.metadata.authorizer.StandardAuthorizer
🔎 延伸阅读:ACL 结构详见 KIP-11 ,资源模式详见 KIP-290 。日常增删查 ACL 使用
kafka-acls.sh。
二、资源无 ACL 的默认行为与"允许所有人"的开关
1)默认:不匹配 ACL = 拒绝访问
当资源(R)未定义任何 ACL(即没有 ACL 命中该资源)时,Kafka 默认限制 访问,只有 super users 可访问。
2)切换为"无 ACL 即允许所有人"
如需改成 没有 ACL 时对所有用户可访问 ,在 server.properties 中加入:
properties
allow.everyone.if.no.acl.found=true
说明:一旦资源存在一条或多条 ACL,则仍以 ACL 的匹配规则为准,与上述开关无关。
3)配置超级用户
分隔符为分号(SSL 用户名可能包含逗号);默认 PrincipalType 字符串 "User" 区分大小写:
properties
super.users=User:Bob;User:Alice
三、KRaft 中的 Principal 转发(Envelope)
在 KRaft 集群 里,客户端的管理类请求(如 CreateTopics/DeleteTopics)先发往 broker 的监听器,broker 再通过 controller.listener.names 中第一个监听器 将请求转发给 active controller 。
授权 在 controller 上完成,机制为 Envelope :将底层请求 与客户端 principal一并封装转发。
- controller 首先用 已认证的 broker principal 授权 Envelope 请求;
- 然后用 被转发的客户端 principal 授权底层请求。
因此,Kafka 必须会序列化/反序列化客户端 principal。若自定义 principal,需要:
- 通过
principal.builder.class覆盖构建器;- 该类实现
org.apache.kafka.common.security.auth.KafkaPrincipalSerde(用于序列化/反序列化 principal)。默认构建器:
org.apache.kafka.common.security.authenticator.DefaultKafkaPrincipalBuilder使用 RPC 定义:
clients/src/main/resources/common/message/DefaultPrincipalData.json
四、映射用户名:SSL 与 SASL(Kerberos)
1)SSL 用户名映射:ssl.principal.mapping.rules
默认 SSL 用户名形如:
"CN=writeuser,OU=Unknown,O=Unknown,L=Unknown,ST=Unknown,C=Unknown"
可用 ssl.principal.mapping.rules 将 X.500 DN 映射为短名。按序匹配 ,首次命中即用,后续忽略;支持 /L(小写)、/U(大写):
text
RULE:pattern/replacement/
RULE:pattern/replacement/[LU]
示例(含大小写规范及通配):
properties
ssl.principal.mapping.rules=\
RULE:^CN=(.*?),OU=ServiceUsers.*$/$1/,\
RULE:^CN=(.*?),OU=(.*?),O=(.*?),L=(.*?),ST=(.*?),C=(.*?)$/$1@$2/L,\
RULE:^.*[Cc][Nn]=([a-zA-Z0-9.]*).*$/$1/L,\
DEFAULT
"CN=serviceuser,OU=ServiceUsers,..." → "serviceuser""CN=adminUser,OU=Admin,..." → "adminuser@admin"
自定义 PrincipalBuilder:
properties
principal.builder.class=CustomizedPrincipalBuilderClass
2)SASL(Kerberos)用户名映射:sasl.kerberos.principal.to.local.rules
默认 SASL 用户名为 Kerberos principal 的 primary 部分。可在 server.properties 中用与 krb5.conf 中 auth_to_local 同构的规则改写(同样支持 /L、/U):
text
RULE:[n:string](regexp)s/pattern/replacement/
RULE:[n:string](regexp)s/pattern/replacement/g
RULE:[n:string](regexp)s/pattern/replacement//L
RULE:[n:string](regexp)s/pattern/replacement/g/L
RULE:[n:string](regexp)s/pattern/replacement//U
RULE:[n:string](regexp)s/pattern/replacement/g/U
示例 :将 user@MYDOMAIN.COM → user,同时保留默认规则:
properties
sasl.kerberos.principal.to.local.rules=\
RULE:[1:$1@$0](.*@MYDOMAIN.COM)s/@.*//,DEFAULT
五、kafka-acls.sh:CLI 全参与高频用法
CLI 位于 bin/ 目录,脚本名 kafka-acls.sh。参数全集(与官方一致):
-
动作类 :
--add、--remove、--list -
连接配置 :
--bootstrap-server(连 broker)、--bootstrap-controller(连 controller)二选一
--command-config(Admin Client 用属性文件,仅配合--bootstrap-server) -
资源模式 :
--cluster、--topic [topic-name]、--group [group-name]、
--transactional-id [transactional-id](*=全部)、
--delegation-token [delegation-token](*=全部)、
--user-principal [user-principal](现用于 delegation tokens;*=全部)、
--resource-pattern-type [pattern-type]:添加时literal|prefixed;列出/移除时可any|match⚠️
--remove+match慎用(会批量移除所有匹配模式的 ACL) -
主体与来源 :
--allow-principal、--deny-principal、--principal(列出时过滤)
--allow-host、--deny-host(仅 IP ,不支持主机名;未显式指定时默认*) -
操作名 :
Read|Write|Create|Delete|Alter|Describe|ClusterAction|DescribeConfigs|AlterConfigs|IdempotentWrite|CreateTokens|DescribeTokens|All -
便捷选项 :
--producer(生成 WRITE/DESCRIBE/CREATE@topic)
--consumer(生成 READ/DESCRIBE@topic + READ@group)
--idempotent(与--producer同用;或由 transactional-id 授权自动启用)
--force(无交互确认)
典型操作示例
1)添加 :允许 User:Bob 与 User:Alice 从指定 IP 对 Test-topic 执行 Read/Write:
bash
bin/kafka-acls.sh --bootstrap-server localhost:9092 --add \
--allow-principal User:Bob \
--allow-principal User:Alice \
--allow-host 198.51.100.0 \
--allow-host 198.51.100.1 \
--operation Read --operation Write \
--topic Test-topic
2)"允许所有 + 拒绝个别" :允许所有用户从任意主机读 Test-topic,但拒绝 User:BadBob 自 198.51.100.3 读取:
bash
bin/kafka-acls.sh --bootstrap-server localhost:9092 --add \
--allow-principal User:'*' --allow-host '*' \
--deny-principal User:BadBob --deny-host 198.51.100.3 \
--operation Read --topic Test-topic
3)对所有 Topic(通配 *)授 Producer 权限:
bash
bin/kafka-acls.sh --bootstrap-server localhost:9092 --add \
--allow-principal User:Peter \
--allow-host 198.51.200.1 \
--producer --topic '*'
4)前缀模式 :允许 User:Jane 向以 Test- 开头的主题生产:
bash
bin/kafka-acls.sh --bootstrap-server localhost:9092 --add \
--allow-principal User:Jane \
--producer --topic Test- \
--resource-pattern-type prefixed
5)移除 ACL (与添加相同参数,改 --remove 即可):
bash
bin/kafka-acls.sh --bootstrap-server localhost:9092 --remove \
--allow-principal User:Bob --allow-principal User:Alice \
--allow-host 198.51.100.0 --allow-host 198.51.100.1 \
--operation Read --operation Write \
--topic Test-topic
6)列出 ACL:
-
精确资源(literal):
bashbin/kafka-acls.sh --bootstrap-server localhost:9092 --list --topic Test-topic -
通配
*:bashbin/kafka-acls.sh --bootstrap-server localhost:9092 --list --topic '*' -
列出影响
Test-topic的全部(含 literal、wildcard、prefixed):bashbin/kafka-acls.sh --bootstrap-server localhost:9092 --list \ --topic Test-topic --resource-pattern-type match
7)按"角色"快速授权:
-
设
User:Bob为Test-topic生产者:bashbin/kafka-acls.sh --bootstrap-server localhost:9092 --add \ --allow-principal User:Bob --producer --topic Test-topic -
设
User:Bob为Test-topic消费者 ,消费组Group-1(必须 指定--group):bashbin/kafka-acls.sh --bootstrap-server localhost:9092 --add \ --allow-principal User:Bob --consumer --topic Test-topic --group Group-1
六、授权原语:操作(Operations)与资源(Resources)
1)操作集合
Read | Write | Create | Delete | Alter | Describe | ClusterAction | DescribeConfigs | AlterConfigs | IdempotentWrite | CreateTokens | DescribeTokens | All
2)资源集合与错误码
- Topic :主题。失败 →
TOPIC_AUTHORIZATION_FAILED (29) - Group :消费组。失败 →
GROUP_AUTHORIZATION_FAILED (30) - Cluster :集群。失败 →
CLUSTER_AUTHORIZATION_FAILED (31) - TransactionalId :事务标识。失败 →
TRANSACTIONAL_ID_AUTHORIZATION_FAILED (53) - DelegationToken:委派令牌(详见 KIP-48)
- User :用户(
CreateToken/DescribeToken可授予到 User,详见 KIP-373)
七、权责矩阵:Kafka 协议 × 操作 × 资源(完整版)
下表直接复刻官方映射(按原文顺序),用于设计"最小权限 "与审计 。
注:若同一 API 同时列出多条,表示该请求可能触达多种授权路径或需要叠加校验。
| Protocol (API key) | Operation | Resource | Note |
|---|---|---|---|
| PRODUCE (0) | Write | TransactionalId | 事务生产者设置了 transactional.id 时需要。 |
| PRODUCE (0) | IdempotentWrite | Cluster | 幂等写。 |
| PRODUCE (0) | Write | Topic | 普通生产。 |
| FETCH (1) | ClusterAction | Cluster | follower 拉取分区数据。 |
| FETCH (1) | Read | Topic | 普通消费者读取分区。 |
| LIST_OFFSETS (2) | Describe | Topic | --- |
| METADATA (3) | Describe | Topic | --- |
| METADATA (3) | Create | Cluster | 自动建主题先查集群级;无则查 Topic 级。 |
| METADATA (3) | Create | Topic | 自动建主题(当集群级无权限)。 |
| LEADER_AND_ISR (4) | ClusterAction | Cluster | --- |
| STOP_REPLICA (5) | ClusterAction | Cluster | --- |
| UPDATE_METADATA (6) | ClusterAction | Cluster | --- |
| CONTROLLED_SHUTDOWN (7) | ClusterAction | Cluster | --- |
| OFFSET_COMMIT (8) | Read | Group | 先组后题。 |
| OFFSET_COMMIT (8) | Read | Topic | --- |
| OFFSET_FETCH (9) | Describe | Group | 先组后题。 |
| OFFSET_FETCH (9) | Describe | Topic | --- |
| FIND_COORDINATOR (10) | Describe | Group | 请求类型为 Group 时。 |
| FIND_COORDINATOR (10) | Describe | TransactionalId | 事务生产者找事务协调者。 |
| JOIN_GROUP (11) | Read | Group | --- |
| HEARTBEAT (12) | Read | Group | --- |
| LEAVE_GROUP (13) | Read | Group | --- |
| SYNC_GROUP (14) | Read | Group | --- |
| DESCRIBE_GROUPS (15) | Describe | Group | --- |
| LIST_GROUPS (16) | Describe | Cluster | 无权限不报错,回退逐组检查。 |
| LIST_GROUPS (16) | Describe | Group | 全未授权时返回空(自 2.1 起)。 |
| SASL_HANDSHAKE (17) | --- | --- | 认证流程,无法授权。 |
| API_VERSIONS (18) | --- | --- | 握手流程,无法授权。 |
| CREATE_TOPICS (19) | Create | Cluster | 无集群级时回退 Topic 级并据此报错。 |
| CREATE_TOPICS (19) | Create | Topic | 自 2.0 起。 |
| DELETE_TOPICS (20) | Delete | Topic | --- |
| DELETE_RECORDS (21) | Delete | Topic | --- |
| INIT_PRODUCER_ID (22) | Write | TransactionalId | --- |
| INIT_PRODUCER_ID (22) | IdempotentWrite | Cluster | --- |
| OFFSET_FOR_LEADER_EPOCH (23) | ClusterAction | Cluster | 无集群级则查 Topic 级。 |
| OFFSET_FOR_LEADER_EPOCH (23) | Describe | Topic | 自 2.1 起。 |
| ADD_PARTITIONS_TO_TXN (24) | Write | TransactionalId | 仅事务请求;先 TxnId 后 Topic。 |
| ADD_PARTITIONS_TO_TXN (24) | Write | Topic | --- |
| ADD_OFFSETS_TO_TXN (25) | Write | TransactionalId | 仅事务请求;先 TxnId 后 Group。 |
| ADD_OFFSETS_TO_TXN (25) | Read | Group | --- |
| END_TXN (26) | Write | TransactionalId | --- |
| WRITE_TXN_MARKERS (27) | Alter | Cluster | --- |
| WRITE_TXN_MARKERS (27) | ClusterAction | Cluster | --- |
| TXN_OFFSET_COMMIT (28) | Write | TransactionalId | --- |
| TXN_OFFSET_COMMIT (28) | Read | Group | --- |
| TXN_OFFSET_COMMIT (28) | Read | Topic | --- |
| DESCRIBE_ACLS (29) | Describe | Cluster | --- |
| CREATE_ACLS (30) | Alter | Cluster | --- |
| DELETE_ACLS (31) | Alter | Cluster | --- |
| DESCRIBE_CONFIGS (32) | DescribeConfigs | Cluster | 查 broker 配置时。 |
| DESCRIBE_CONFIGS (32) | DescribeConfigs | Topic | 查 topic 配置时。 |
| ALTER_CONFIGS (33) | AlterConfigs | Cluster | 改 broker 配置时。 |
| ALTER_CONFIGS (33) | AlterConfigs | Topic | 改 topic 配置时。 |
| ALTER_REPLICA_LOG_DIRS (34) | Alter | Cluster | --- |
| DESCRIBE_LOG_DIRS (35) | Describe | Cluster | 未授权返回空。 |
| SASL_AUTHENTICATE (36) | --- | --- | 认证流程,无法授权。 |
| CREATE_PARTITIONS (37) | Alter | Topic | --- |
| CREATE_DELEGATION_TOKEN (38) | --- | --- | 特殊规则,见 Delegation Tokens。 |
| CREATE_DELEGATION_TOKEN (38) | CreateTokens | User | 允许为 User 创建委派令牌。 |
| RENEW_DELEGATION_TOKEN (39) | --- | --- | 特殊规则。 |
| EXPIRE_DELEGATION_TOKEN (40) | --- | --- | 特殊规则。 |
| DESCRIBE_DELEGATION_TOKEN (41) | Describe | DelegationToken | 特殊规则。 |
| DESCRIBE_DELEGATION_TOKEN (41) | DescribeTokens | User | 允许描述 User 的委派令牌。 |
| DELETE_GROUPS (42) | Delete | Group | --- |
| ELECT_PREFERRED_LEADERS (43) | ClusterAction | Cluster | --- |
| INCREMENTAL_ALTER_CONFIGS (44) | AlterConfigs | Cluster | 改 broker 配置。 |
| INCREMENTAL_ALTER_CONFIGS (44) | AlterConfigs | Topic | 改 topic 配置。 |
| ALTER_PARTITION_REASSIGNMENTS (45) | Alter | Cluster | --- |
| LIST_PARTITION_REASSIGNMENTS (46) | Describe | Cluster | --- |
| OFFSET_DELETE (47) | Delete | Group | --- |
| OFFSET_DELETE (47) | Read | Topic | --- |
| DESCRIBE_CLIENT_QUOTAS (48) | DescribeConfigs | Cluster | --- |
| ALTER_CLIENT_QUOTAS (49) | AlterConfigs | Cluster | --- |
| DESCRIBE_USER_SCRAM_CREDENTIALS (50) | Describe | Cluster | --- |
| ALTER_USER_SCRAM_CREDENTIALS (51) | Alter | Cluster | --- |
| VOTE (52) | ClusterAction | Cluster | --- |
| BEGIN_QUORUM_EPOCH (53) | ClusterAction | Cluster | --- |
| END_QUORUM_EPOCH (54) | ClusterAction | Cluster | --- |
| DESCRIBE_QUORUM (55) | Describe | Cluster | --- |
| ALTER_PARTITION (56) | ClusterAction | Cluster | --- |
| UPDATE_FEATURES (57) | Alter | Cluster | --- |
| ENVELOPE (58) | ClusterAction | Cluster | --- |
| FETCH_SNAPSHOT (59) | ClusterAction | Cluster | --- |
| DESCRIBE_CLUSTER (60) | Describe | Cluster | --- |
| DESCRIBE_PRODUCERS (61) | Read | Topic | --- |
| BROKER_REGISTRATION (62) | ClusterAction | Cluster | --- |
| BROKER_HEARTBEAT (63) | ClusterAction | Cluster | --- |
| UNREGISTER_BROKER (64) | Alter | Cluster | --- |
| DESCRIBE_TRANSACTIONS (65) | Describe | TransactionalId | --- |
| LIST_TRANSACTIONS (66) | Describe | TransactionalId | --- |
| ALLOCATE_PRODUCER_IDS (67) | ClusterAction | Cluster | --- |
| CONSUMER_GROUP_HEARTBEAT (68) | Read | Group | --- |
| CONSUMER_GROUP_DESCRIBE (69) | Read | Group | --- |
| CONTROLLER_REGISTRATION (70) | ClusterAction | Cluster | --- |
| GET_TELEMETRY_SUBSCRIPTIONS (71) | --- | --- | 无授权检查。 |
| PUSH_TELEMETRY (72) | --- | --- | 无授权检查。 |
| ASSIGN_REPLICAS_TO_DIRS (73) | ClusterAction | Cluster | --- |
| LIST_CONFIG_RESOURCES (74) | DescribeConfigs | Cluster | --- |
| DESCRIBE_TOPIC_PARTITIONS (75) | Describe | Topic | --- |
| SHARE_GROUP_HEARTBEAT (76) | Read | Group | --- |
| SHARE_GROUP_DESCRIBE (77) | Describe | Group | --- |
| SHARE_FETCH (78) | Read | Group | --- |
| SHARE_FETCH (78) | Read | Topic | --- |
| SHARE_ACKNOWLEDGE (79) | Read | Group | --- |
| SHARE_ACKNOWLEDGE (79) | Read | Topic | --- |
| INITIALIZE_SHARE_GROUP_STATE (83) | ClusterAction | Cluster | --- |
| READ_SHARE_GROUP_STATE (84) | ClusterAction | Cluster | --- |
| WRITE_SHARE_GROUP_STATE (85) | ClusterAction | Cluster | --- |
| DELETE_SHARE_GROUP_STATE (86) | ClusterAction | Cluster | --- |
| READ_SHARE_GROUP_STATE_SUMMARY (87) | ClusterAction | Cluster | --- |
| STREAMS_GROUP_HEARTBEAT (88) | Read | Group | --- |
| STREAMS_GROUP_HEARTBEAT (88) | Describe | Topic | 需要对所有源主题 与内部主题授权。 |
| STREAMS_GROUP_HEARTBEAT (88) | Create | Topic | 允许 broker 自动创建内部主题(若不存在)。 |
| STREAMS_GROUP_DESCRIBE (89) | Describe | Group | --- |
| STREAMS_GROUP_DESCRIBE (89) | Describe | Topic | 需要对所有源/内部主题授权。 |
| DESCRIBE_SHARE_GROUP_OFFSETS (90) | Describe | Group | 先组后题。 |
| DESCRIBE_SHARE_GROUP_OFFSETS (90) | Describe | Topic | --- |
| ALTER_SHARE_GROUP_OFFSETS (91) | Read | Group | 先组后题。 |
| ALTER_SHARE_GROUP_OFFSETS (91) | Read | Topic | --- |
| DELETE_SHARE_GROUP_OFFSETS (92) | Delete | Group | 先组后题。 |
| DELETE_SHARE_GROUP_OFFSETS (92) | Read | Topic | --- |
八、工程落地:最小权限、命名规范与排错清单
1)最小权限策略(示例)
- 生产者(普通) :
Write@Topic:<t>+ (如需)IdempotentWrite@Cluster - 消费者(普通) :
Read@Topic:<t>+Read@Group:<g> - 事务生产者 :
Write@TransactionalId:<txid>+Write@Topic:<t>(以及必要时的 IdempotentWrite@Cluster) - Streams :为所有源主题与内部主题 赋
Describe@Topic;若允许自动创建内部主题 ,再赋Create@Topic(或事先创建并仅给 Describe)
2)主体与主机规则
- 优先用 短名(SSL/SASL 映射)避免 DN/Realm/大小写问题。
--allow-host/--deny-host仅支持 IP;如需按网段限制,建议运维层控制或生成工具扩展。
3)资源模式
- **精确(literal)**用于"按名授权",**通配('*')**慎用。
- **前缀(prefixed)**适合多租户/批量主题,但需严格命名规范与审计。
- 清理 ACL 时避免盲用
--remove --resource-pattern-type match。
4)"无 ACL"策略开关
- 默认拒绝 安全性更高;若开启
allow.everyone.if.no.acl.found=true,务必配合 CI/CD 审计防止"漏配即放开"。
5)KRaft Principal 转发
- 定制 principal 时记得实现
KafkaPrincipalSerde;否则 Envelope 上下游序列化失败。
6)故障排查
- 错误码定位:
TOPIC_AUTHORIZATION_FAILED(29)、GROUP_AUTHORIZATION_FAILED(30)、CLUSTER_AUTHORIZATION_FAILED(31)、TRANSACTIONAL_ID_AUTHORIZATION_FAILED(53)。 - 若
LIST_GROUPS返回空但不报错,考虑是权限不足导致的空集合(2.1+ 行为)。
九、运维脚本模板(占位符示例)
将
<BS>、<TOPIC>、<GROUP>、<USER>替换为实际值。
bash
# Producer (literal)
bin/kafka-acls.sh --bootstrap-server <BS> --add \
--allow-principal User:<USER> --producer --topic <TOPIC>
# Consumer (literal)
bin/kafka-acls.sh --bootstrap-server <BS> --add \
--allow-principal User:<USER> --consumer --topic <TOPIC> --group <GROUP>
# Idempotent Producer (cluster-level)
bin/kafka-acls.sh --bootstrap-server <BS> --add \
--allow-principal User:<USER> --operation IdempotentWrite --cluster
# Streams 内部主题自动创建(前缀)
bin/kafka-acls.sh --bootstrap-server <BS> --add \
--allow-principal User:<USER> --operation Create \
--topic <INTERNAL_PREFIX> --resource-pattern-type prefixed
十、结语
本文按 KRaft 语义与官方结构,提供了 Kafka 授权体系的 全量知识面 :从 Authorizer 启用、无 ACL 策略、super users,到 Envelope 转发与 principal 序列化契约;从 SSL/SASL 用户名映射的正则规则到 CLI 全参;再到覆盖 Streams/事务/共享组在内的 协议×操作×资源矩阵。