Kafka ACLs
Access Control Lists are how Kafka decides who's allowed to do what. They work, they're native, and they scale badly. Here's how to configure them, the defaults that catch most teams out, and when it's time to layer RBAC on top.
What a Kafka ACL actually is
An ACL (Access Control List) in Kafka is an allow rule. Each entry maps a principal (like User:alice) to an operation (Read, Write, Create, Describe, Alter) on a specific resource (Topic, ConsumerGroup, Cluster, TransactionalId). If a request doesn't match at least one allow rule, the broker denies it.
ACLs live inside the Kafka cluster itself. They're stored in KRaft (or ZooKeeper on older deployments) and enforced by the broker on every request.
Turning ACLs on
ACLs are off by default. Without them, every authenticated principal can do anything. Turn them on in broker.properties before connecting any clients you actually care about:
# broker.properties
authorizer.class.name=org.apache.kafka.metadata.authorizer.StandardAuthorizer
super.users=User:admin
allow.everyone.if.no.acl.found=false The most common mistake here is leaving allow.everyone.if.no.acl.found=true. That flag makes Kafka fall back to "allow" when no ACL exists, which defeats the whole point. Set it to false so the broker denies any request that isn't explicitly permitted.
Adding ACLs with the CLI
Kafka ships with kafka-acls.sh for adding, listing, and removing rules:
# Grant alice read access to a topic
bin/kafka-acls.sh --bootstrap-server localhost:9092 \
--add --allow-principal User:alice \
--operation Read --topic customer-events
# List all ACLs on a cluster
bin/kafka-acls.sh --bootstrap-server localhost:9092 --list
# Remove an ACL
bin/kafka-acls.sh --bootstrap-server localhost:9092 \
--remove --allow-principal User:alice \
--operation Read --topic customer-events Each grant is per-principal, per-operation, per-resource. No groups, no role inheritance, no bulk patterns beyond wildcard topic matching.
Where ACLs stop working
For small clusters with a handful of users, ACLs are fine. Past that, four things start to hurt:
- No groups. Every ACL is per-principal. Onboarding ten new engineers means adding ten sets of ACLs one at a time.
- No role inheritance. A "developer" role doesn't exist natively, so you reproduce the same permissions for every developer principal.
- No audit trail. The broker doesn't log who added which ACL when, so when an auditor asks about change history, you don't have one.
- No cross-cluster view. Listing ACLs across five clusters means running
kafka-acls.sh --listfive times and diffing the output.
Most teams start with raw ACLs, scale past the point where they're manageable, and end up layering RBAC on top. The ACLs stay. They're still the enforcement layer at the broker. Something else just manages them.
ACLs vs RBAC
ACLs and RBAC aren't competing technologies; they stack. RBAC handles the who and what role at the identity layer (users, groups, roles), then translates those assignments into the ACLs the broker actually enforces. You get the usability of roles and groups, and the broker still enforces the low-level rules it's always enforced.
For the full picture (how ACLs fit alongside encryption, authentication, and auditing), read the Kafka Security Guide. For the RBAC side specifically, see Kafka RBAC.
Frequently asked questions
Are Kafka ACLs enabled by default?
No. Out of the box, Kafka has no authorizer configured, so any authenticated principal can do anything. Set authorizer.class.name in broker.properties to turn them on.
What happens if I turn on ACLs without defining any?
With allow.everyone.if.no.acl.found=true (the old default), the broker allows everything. That defeats the point. With allow.everyone.if.no.acl.found=false, the broker denies everything, including your own admin user, so add a super.users entry first.
Can I use ACLs without authentication?
Technically yes, but it's pointless. The broker can't enforce a per-principal rule if no principal has been authenticated. ACLs assume TLS, SASL, or mTLS is already in place.
How do I audit ACL changes?
Kafka's Log4j authorizer logger captures ACL updates when configured, but there's no native history or query UI. Ship the log output to a SIEM (Splunk, ELK, Datadog) for searchable history.
Do ACLs apply to consumer groups?
Yes. Consumer group operations (join, leave, commit offsets) are a separate resource type. Read access to a topic doesn't include consumer-group access; both need explicit ACLs.
I have more questions.
Drop us a line and we'll get back to you.
Going beyond ACLs?
See how Conduktor layers RBAC, audit trails, and cross-cluster ACL management on top of your existing brokers, without replacing Kafka's native enforcement.