一、授权框架概览:开启可插拔 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/事务/共享组在内的 协议×操作×资源矩阵。