Kafka 3.2 puts KRaft ACLs in the metadata log
StandardAuthorizer stores authorization state through Kafka's self-managed metadata machinery. The release also replaces the Log4j 1.x backend with reload4j, with different implications for applications and bundled tools.
Removing an external metadata system requires deciding where authorization state belongs. Kafka 3.2 adds StandardAuthorizer for KRaft, making ACLs part of the self-managed metadata model. The May 17 release summary identifies the work as KIP-801. It also records the replacement of Log4j 1.x with reload4j, another change whose practical scope depends on which Kafka component an application uses.
The authorizer addition has a direct architectural meaning. Kafka needs a representation of permissions that participates in its metadata lifecycle. Creating an ACL must produce durable state, while replaying that state must update the authorizer used by requests. A class implementing permission checks is only one part of that requirement.
I value Kafka's use of retained history for application data. Applying a log-based model to metadata is interesting for the same reason, because it makes state reconstruction part of the design. Authorization adds a requirement that reconstructed state correspond to the permissions the cluster should enforce.
ACL creation becomes a metadata operation
The ClusterMetadataAuthorizer interface explicitly describes authorizers that store state in __cluster_metadata. It exposes methods to load snapshots and add or remove ACLs by ID. This gives the metadata subsystem a defined way to supply state to the permission-checking implementation.
The interface's creation operation returns a future for each requested ACL binding. Its documentation connects completion to persistence in the cluster metadata log and addition on the controller. The active controller performs mutations, and a request in the wrong controller context can fail with NOT_CONTROLLER.
That division distinguishes an accepted administrative request from an isolated in-memory modification. The mutation has a place in the durable metadata sequence. Consumers of that sequence can reconstruct the corresponding authorization state through the replay methods.
Deletion similarly works through filters and completion results. Removing a permission is a metadata change with its own result, not merely an instruction to erase an entry from whichever broker received the call. The same state needs to be represented consistently wherever the cluster uses it for authorization.
The controller stores ACL identities and records
The AclControlManager implementation manages ACLs stored in the metadata topic. It maintains an ID-to-ACL map and a set of existing ACLs. New entries receive generated UUIDs, and additions produce access-control-entry records.
The validation code accepts literal and prefixed resource patterns. It rejects unknown resource types and invalid operation or permission values. Those checks keep the creation request concrete. A filter intended to select several possible entries is not automatically a valid new ACL definition.
When the same ACL already exists, the controller can return success without creating another record for a duplicate. The explicit identity assigned to a stored ACL then gives deletion a concrete target. Removal records identify the ACL by ID, allowing replay to remove the corresponding state.
The replay methods update the controller's maps and, outside snapshot loading, inform the authorizer of additions and removals. This is the mechanism connecting a metadata record with the runtime permission view. The code provides a more specific explanation than saying KRaft now supports security.
Snapshot loading uses a full map of ACL identities and definitions. StandardAuthorizer replaces its current ACL data with the supplied snapshot through loadSnapshot. Anything absent from that map is no longer part of the loaded view. This differs from applying one incremental addition, which updates a particular identity while preserving the rest. Both operations are necessary to represent recovery and ongoing metadata changes through the same authorizer.
Permission evaluation is a separate operation
The StandardAuthorizer implementation receives a request context and a list of actions to authorize. It evaluates each action through its current authorization data and returns corresponding results. Updating ACL state and evaluating a request therefore remain separate responsibilities.
The configuration includes super.users and allow.everyone.if.no.acl.found. The latter defaults to denial when absent. Changing it alters the default authorization result, so it is a policy decision independent of where ACLs are stored.
My preference is to preserve that distinction when explaining this release. Moving permission state into Kafka's metadata machinery does not decide an organization's policy. It supplies a storage and evaluation path through which the chosen policy can operate.
Logging changes depend on the module
The 3.2 upgrade notes say Kafka replaces log4j and slf4j-log4j12 with reload4j and slf4j-reload4j because of security concerns. They distinguish modules that specify a logging backend from modules that let the containing application choose one.
Connect runtime and Kafka tools are examples of the first category. kafka-clients is an example of the second. An application using the client library should therefore examine its own selected backend rather than assume the broker distribution's replacement automatically changes the application's dependency graph.
The notes recommend slf4j-log4j12 version 1.7.35 or later, or slf4j-reload4j, for projects depending on affected modules. That guidance addresses compatibility at the logging integration point. It does not establish that every application using Kafka directly depended on the removed backend.
The release separates storage choices from application contracts
Kafka 3.2 also corrects the producer's idempotence default when no conflicting settings are present. Its upgrade notes name 3.0.1 and 3.1.1 as other releases containing that correction. They explicitly note that Connect continues to disable idempotence by default for its producers to support a broad broker-version range.
That exception illustrates the importance of component scope across this release. StandardAuthorizer supplies ACL storage for KRaft. Logging backend changes apply to particular modules, and producer defaults have a documented Connect exception. The practical meaning of upgrading depends on the component and execution path in use, with the new authorizer making permission state a concrete part of Kafka's metadata log.