Skip to content

AxonOps — AI-Native Control Plane for Open Source Data Platforms

Kafka Authorization

Access Control Lists (ACLs) control which principals can perform which operations on which resources.


ComponentDescriptionExamples
PrincipalIdentity performing actionUser:alice, User:CN=client.example.com
PermissionAllow or DenyALLOW, DENY
OperationAction to performRead, Write, Create, Delete
ResourceKafka resourceTopic:orders, Group:processors
HostSource IP*, 192.168.1.100
ResourceDescriptionOperations
TopicKafka topicRead, Write, Create, Delete, Describe, Alter
GroupConsumer groupRead, Describe, Delete
ClusterCluster-wideCreate, Alter, Describe, ClusterAction
TransactionalIdTransaction IDWrite, Describe
DelegationTokenDelegation tokensDescribe
OperationDescription
ReadConsume from topic, read consumer group offsets
WriteProduce to topic
CreateCreate topics
DeleteDelete topics, delete consumer groups
DescribeView topic/group metadata
AlterModify topic/broker configuration
AlterConfigsModify configurations
DescribeConfigsView configurations
ClusterActionInter-broker communication
IdempotentWriteIdempotent producer writes
AllAll operations

server.properties
# Enable ACL authorizer
authorizer.class.name=org.apache.kafka.metadata.authorizer.StandardAuthorizer
# Super users (bypass ACLs)
super.users=User:admin;User:kafka-broker
# Default behavior when no ACL matches
# false = deny (recommended for production)
# true = allow (for testing/migration)
allow.everyone.if.no.acl.found=false
# Principal builder for extracting identity
principal.builder.class=org.apache.kafka.common.security.authenticator.DefaultKafkaPrincipalBuilder

AxonOps provides a dashboard interface for configuring authorization settings across all brokers without manual configuration file editing.


Terminal window
# Producer access to topic
kafka-acls.sh --bootstrap-server kafka:9092 \
--add \
--allow-principal User:producer-app \
--operation Write \
--operation Describe \
--topic orders
# Consumer access to topic and group
kafka-acls.sh --bootstrap-server kafka:9092 \
--add \
--allow-principal User:consumer-app \
--operation Read \
--operation Describe \
--topic orders \
--group order-processors
# Idempotent producer
kafka-acls.sh --bootstrap-server kafka:9092 \
--add \
--allow-principal User:producer-app \
--operation IdempotentWrite \
--cluster
# Transactional producer
kafka-acls.sh --bootstrap-server kafka:9092 \
--add \
--allow-principal User:producer-app \
--operation Write \
--transactional-id my-txn-id
kafka-acls.sh --bootstrap-server kafka:9092 \
--add \
--allow-principal User:producer-app \
--operation Describe \
--transactional-id my-txn-id
Terminal window
# All ACLs
kafka-acls.sh --bootstrap-server kafka:9092 --list
# For specific topic
kafka-acls.sh --bootstrap-server kafka:9092 \
--list --topic orders
# For specific principal
kafka-acls.sh --bootstrap-server kafka:9092 \
--list --principal User:producer-app
Terminal window
kafka-acls.sh --bootstrap-server kafka:9092 \
--remove \
--allow-principal User:producer-app \
--operation Write \
--topic orders

AxonOps provides a visual interface for managing ACLs without command-line operations. ACL changes are tracked in audit logs with the user who made the change, timestamp, and before/after state.


Terminal window
# Basic producer
kafka-acls.sh --bootstrap-server kafka:9092 \
--add \
--allow-principal User:my-producer \
--operation Write \
--operation Describe \
--topic my-topic
# Idempotent producer (recommended)
kafka-acls.sh --bootstrap-server kafka:9092 \
--add \
--allow-principal User:my-producer \
--operation Write \
--operation Describe \
--topic my-topic
kafka-acls.sh --bootstrap-server kafka:9092 \
--add \
--allow-principal User:my-producer \
--operation IdempotentWrite \
--cluster
Terminal window
kafka-acls.sh --bootstrap-server kafka:9092 \
--add \
--allow-principal User:my-consumer \
--operation Read \
--operation Describe \
--topic my-topic
kafka-acls.sh --bootstrap-server kafka:9092 \
--add \
--allow-principal User:my-consumer \
--operation Read \
--group my-consumer-group
Terminal window
# Connect worker
kafka-acls.sh --bootstrap-server kafka:9092 \
--add \
--allow-principal User:kafka-connect \
--operation Read \
--operation Write \
--operation Create \
--topic connect-configs
kafka-acls.sh --bootstrap-server kafka:9092 \
--add \
--allow-principal User:kafka-connect \
--operation Read \
--operation Write \
--operation Create \
--topic connect-offsets
kafka-acls.sh --bootstrap-server kafka:9092 \
--add \
--allow-principal User:kafka-connect \
--operation Read \
--operation Write \
--operation Create \
--topic connect-status
kafka-acls.sh --bootstrap-server kafka:9092 \
--add \
--allow-principal User:kafka-connect \
--operation Read \
--group connect-cluster
# Connector data topics
kafka-acls.sh --bootstrap-server kafka:9092 \
--add \
--allow-principal User:kafka-connect \
--operation Read \
--operation Write \
--operation Describe \
--topic 'connector-*' \
--resource-pattern-type prefixed
Terminal window
# Internal topics
kafka-acls.sh --bootstrap-server kafka:9092 \
--add \
--allow-principal User:streams-app \
--operation All \
--topic 'streams-app-*' \
--resource-pattern-type prefixed
# Input/output topics
kafka-acls.sh --bootstrap-server kafka:9092 \
--add \
--allow-principal User:streams-app \
--operation Read \
--topic input-topic
kafka-acls.sh --bootstrap-server kafka:9092 \
--add \
--allow-principal User:streams-app \
--operation Write \
--topic output-topic
# Consumer group
kafka-acls.sh --bootstrap-server kafka:9092 \
--add \
--allow-principal User:streams-app \
--operation Read \
--group streams-app
Terminal window
# Full admin access
kafka-acls.sh --bootstrap-server kafka:9092 \
--add \
--allow-principal User:admin \
--operation All \
--cluster
kafka-acls.sh --bootstrap-server kafka:9092 \
--add \
--allow-principal User:admin \
--operation All \
--topic '*'
kafka-acls.sh --bootstrap-server kafka:9092 \
--add \
--allow-principal User:admin \
--operation All \
--group '*'

Terminal window
# Exact match
kafka-acls.sh --bootstrap-server kafka:9092 \
--add \
--allow-principal User:app \
--operation Read \
--topic orders \
--resource-pattern-type literal
Terminal window
# Match topics starting with "events-"
kafka-acls.sh --bootstrap-server kafka:9092 \
--add \
--allow-principal User:app \
--operation Read \
--topic events- \
--resource-pattern-type prefixed
Terminal window
# All topics
kafka-acls.sh --bootstrap-server kafka:9092 \
--add \
--allow-principal User:admin \
--operation All \
--topic '*'

Deny rules take precedence over allow rules.

Terminal window
# Allow all topics except sensitive
kafka-acls.sh --bootstrap-server kafka:9092 \
--add \
--allow-principal User:app \
--operation Read \
--topic '*'
kafka-acls.sh --bootstrap-server kafka:9092 \
--add \
--deny-principal User:app \
--operation Read \
--topic sensitive-data

log4j.properties
log4j.logger.kafka.authorizer.logger=DEBUG
ErrorCauseSolution
TopicAuthorizationExceptionNo Read/Write ACLAdd topic ACL
GroupAuthorizationExceptionNo group Read ACLAdd group ACL
ClusterAuthorizationExceptionNo cluster ACLAdd cluster ACL
TransactionalIdAuthorizationExceptionNo txn ID ACLAdd transactional-id ACL

AxonOps correlates authorization errors with the specific ACLs in place, simplifying troubleshooting by showing which ACL rule caused the denial and what ACL would be needed to allow the operation.


By default, SSL user names follow the full DN format:

CN=writeuser,OU=Unknown,O=Unknown,L=Unknown,ST=Unknown,C=Unknown

Configure ssl.principal.mapping.rules to extract short names:

server.properties
ssl.principal.mapping.rules=\
RULE:^CN=(.*?),OU=ServiceUsers.*$/$1/, \
RULE:^CN=(.*?),OU=(.*?),O=(.*?),L=(.*?),ST=(.*?),C=(.*?)$/$1@$2/L, \
DEFAULT

Rule syntax:

FormatDescription
RULE:pattern/replacement/Basic replacement
RULE:pattern/replacement/LLowercase result
RULE:pattern/replacement/UUppercase result
DEFAULTUse full DN

Examples:

Input DNRuleResult
CN=serviceuser,OU=ServiceUsers,O=CorpRULE:^CN=(.*?),OU=ServiceUsers.*$/$1/serviceuser
CN=AdminUser,OU=Admin,O=CorpRULE:^CN=(.*?),OU=(.*?).*$/$1@$2/Ladminuser@admin

Configure sasl.kerberos.principal.to.local.rules for Kerberos principals:

server.properties
sasl.kerberos.principal.to.local.rules=\
RULE:[1:$1@$0](.*@MYDOMAIN.COM)s/@.*//,\
DEFAULT

Rule syntax:

FormatDescription
RULE:[n:string](regexp)s/pattern/replacement/Standard replacement
RULE:[n:string](regexp)s/pattern/replacement/gGlobal replacement
RULE:[n:string](regexp)s/pattern/replacement//LLowercase result
RULE:[n:string](regexp)s/pattern/replacement//UUppercase result

Each Kafka protocol request requires specific ACL permissions:

ProtocolOperationResourceNotes
PRODUCEWriteTopicNormal produce
PRODUCEIdempotentWriteClusterIdempotent producer
PRODUCEWriteTransactionalIdTransactional producer
FETCHReadTopicConsumer fetch
FETCHClusterActionClusterFollower replication
ProtocolOperationResourceNotes
JOIN_GROUPReadGroupJoin consumer group
SYNC_GROUPReadGroupSynchronize assignments
HEARTBEATReadGroupMaintain membership
LEAVE_GROUPReadGroupLeave group
OFFSET_COMMITReadGroup, TopicCommit offsets
OFFSET_FETCHDescribeGroup, TopicFetch committed offsets
FIND_COORDINATORDescribeGroupFind group coordinator
ProtocolOperationResourceNotes
METADATADescribeTopicGet topic metadata
METADATACreateCluster or TopicAuto-create topics
LIST_OFFSETSDescribeTopicGet partition offsets
CREATE_TOPICSCreateClusterCreate topics
DELETE_TOPICSDeleteTopicDelete topics
ALTER_CONFIGSAlterConfigsTopicModify topic config
DESCRIBE_CONFIGSDescribeConfigsTopicRead topic config
ProtocolOperationResourceNotes
FIND_COORDINATORDescribeTransactionalIdFind txn coordinator
INIT_PRODUCER_IDWriteTransactionalIdInitialize producer
ADD_PARTITIONS_TO_TXNWriteTransactionalId, TopicAdd partitions
ADD_OFFSETS_TO_TXNWriteTransactionalId, GroupAdd offsets
END_TXNWriteTransactionalIdCommit/abort txn
TXN_OFFSET_COMMITReadGroup, TopicCommit txn offsets
WRITE_TXN_MARKERSClusterActionClusterInter-broker
ProtocolOperationResourceNotes
CREATE_PARTITIONSAlterTopicAdd partitions
DELETE_RECORDSDeleteTopicDelete records
ELECT_LEADERSClusterActionClusterLeader election
DESCRIBE_LOG_DIRSDescribeClusterLog directory info
ALTER_REPLICA_LOG_DIRSAlterClusterMove replicas
CREATE_ACLSAlterClusterManage ACLs
DESCRIBE_ACLSDescribeClusterList ACLs
DELETE_ACLSAlterClusterRemove ACLs

In KRaft mode, admin requests flow through brokers to controllers:

  1. Client sends request to broker
  2. Broker wraps request in Envelope with client principal
  3. Controller authorizes broker (Envelope request)
  4. Controller authorizes original request using forwarded principal

For custom principals to work with KRaft, the principal builder must implement KafkaPrincipalSerde:

server.properties
principal.builder.class=com.example.CustomPrincipalBuilder

In Kafka 4.2+ (KIP-1157), KafkaPrincipalBuilder extends KafkaPrincipalSerde directly, providing compile-time enforcement. Custom implementations that do not implement serialization will fail to compile, preventing runtime errors during KRaft principal forwarding.


Managing Kafka ACLs through command-line tools becomes increasingly complex as clusters grow and teams expand. AxonOps provides enterprise-grade ACL management:

  • Topic ACL browser: View and manage ACLs per topic with point-and-click interface
  • Principal view: See all permissions granted to a specific user or service account
  • Bulk operations: Apply ACL templates across multiple topics or consumer groups
  • ACL validation: Preview ACL changes before applying to prevent misconfigurations
  • Role-based permissions: Control which AxonOps users can view, create, or modify ACLs
  • Approval workflows: Require approval for ACL changes in production environments
  • Segregation of duties: Separate ACL management from other Kafka operations
  • Complete audit trail: Every ACL change is logged with user, timestamp, and change details
  • Before/after state: Full record of ACL state before and after each modification
  • Compliance reporting: Export audit logs for security reviews and compliance requirements
  • Integration: Forward audit events to SIEM systems
  • REST API: Programmatic ACL management for automation and CI/CD pipelines
  • Terraform provider: Infrastructure-as-code support for ACL definitions
  • Idempotent operations: Safe to re-apply ACL configurations

See AxonOps Kafka Security for configuration details.