This document describes how to use Apache Kafka access control lists (ACLs) for access control in Google Cloud Managed Service for Apache Kafka.
Apache Kafka ACLs provide fine-grained access control within the Kafka cluster. Managed Service for Apache Kafka enables the out-of-the-box StandardAuthorizer
, which stores ACLs in the KRaft-based Kafka cluster metadata.
These ACLs control which authenticated users can perform specific operations on specific Kafka resources, like producing or consuming messages on a topic.
These ACLs are useful to control interactions with the cluster using standard Apache Kafka clients, which are only subject to a cluster-level IAM check for the initial connection. For more information, see Access control with IAM.
How Kafka ACL access control works
The client interacts with Kafka's standard ACL authorizer within the cluster. The authorizer evaluates the relevant Apache Kafka ACLs to authorize specific operations requested by the principal, such as producing to a topic or consuming from a group. The principal used for the ACL check is derived from one of the following authentication methods:
SASL: the IAM principal such as a service account email.
mTLS: the Distinguished Name (DN) from the client certificate, potentially transformed by principal mapping rules.
For comprehensive security, you must configure the following:
IAM permissions for management access. For more information, see Access control with IAM.
Kafka ACLs for in-cluster data access and operations from open-source Apache Kafka clients, independent of the authentication method.
Usage of Apache Kafka ACLs
Apache Kafka ACL bindings have the following format:
Principal P is [Allowed/Denied] Operation O From Host H on any resource matching Resource Pattern RP.
The following is a list of important information about the format:
Principal(P): The user identity being authorized. This is prefixed with
User:
.For SASL authentication, this is the IAM principal, such as
User:my-service-account@my-project.iam.gserviceaccount.com
.For mTLS authentication, this is the Distinguished Name (DN) from the client certificate, such as
User:CN=my-client,OU=my-org-unit
. The exact format depends on the certificate's Subject. Principal mapping rules can transform this value.
Permission type(Allowed/Denied): whether the ACL binding allows or denies access. Deny bindings take precedence.
Operation(O): the action performed such as Read, Write, or Create. For information about which operations apply to which resources for various Kafka protocols, see [the Apache Kafka documentation](https://kafka.apache.org/documentation/#operations_resources_and_protocols).
Host(H): the machine from which the request originates. Since Managed Service for Apache Kafka translates client network addresses, use of hosts other than
'*'
is not supported.Resource Pattern(RP): a pattern used to match specific resources. A resource pattern consists of a resource type, a resource name, and a pattern type (
LITERAL
orPREFIXED
).
Default access
Managed Service for Apache Kafka clusters operate with the Apache Kafka property allow.everyone.if.no.acl.found
set to true
. The presence or absence of Kafka ACLs directly dictates the level of access to resources:
If no Kafka ACLs are defined for a specific resource like a topic, all authenticated principals are granted access to it. This configuration lets Managed Service for Apache Kafka clusters be immediately operable, without the requirement to configure ACLs.
As soon as you define any Kafka ACL for that resource, access becomes restricted. Only principals explicitly granted permission using an
ALLOW
entry in a Kafka ACL can access matching resources (unless specifically blocked by aDENY
entry).
Managed Service for Apache Kafka gives its service agent administrative access to your cluster. This access allows the service agent to perform operations requested by the Managed Service for Apache Kafka API, regardless of other ACLs configured in the cluster. Managed Service for Apache Kafka accomplishes this by modifying the StandardAuthorizer
implementation. The modification grants the service agent permissions similar to super users, except for read and write operations. You cannot change this configuration.
Kafka principals
Kafka principals for Managed Service for Apache Kafka clusters are specified with the Kafka StandardAuthorizer prefix "User:"
.
For SASL/IAM: the principal is the Google Cloud account. For example, to grant access to the service account
test-kafka-client@test-project.iam.gserviceaccount.com
, use the Kafka principal"User:test-kafka-client@test-project.iam.gserviceaccount.com"
. Kafka ACL principals must specify a user, a service account, or an individual IAM principal, but not a group or principal set. Kafka ACLs don't support resolving group memberships for Google Cloud principals.For mTLS: the principal is derived from the client certificate's Subject Distinguished Name (DN). For example,
User:CN=client1,OU=dev,O=MyOrg,L=City,ST=State,C=US
. You can use mTLS principal mapping rules to transform the DN into a more user-friendly principal string for ACLs.
To create an ACL that applies to all members of a Google Group or principal set, you can use a proxy service account principal and service account impersonation:
Create a service account to use as a proxy for the group.
Grant the Google Group or principal set the Service Account Token Creator role on the service account. See Manage access to service accounts
Add Kafka ACLs for the proxy service account. An example principal would be:
User:group-proxy@test-project.iam.gserviceaccount.com
.Use service account impersonation in Kafka clients to authenticate to Kafka as the service account. Google Cloud IAM authorizes an individual principal as a member of the group that's allowed to impersonate the proxy service account. And Kafka authorizes the proxy service account against existing ACLs in the cluster.
Kafka operations for producers and consumers
An operation is an action performed on a resource. For each resource, an operation is mapped to one or more Kafka protocol requests for that resource. For example, a READ
operation for the topic
resource type is mapped to Fetch
, OffsetCommit
, and TxnOffsetCommit
Apache Kafka protocols.
To grant a principal producer access on a topic, perform the following steps:
On the topic resource, allow the
WRITE
andCREATE
operations.If using transactional IDs, on the transactional ID resource, allow the
WRITE
operation.
To grant a principal consumer access on a topic, perform the following steps:
On the topic resource, allow the
READ
operation.On the consumer group resource, allow the
READ
operation.
For more information about the valid operations on resources that the Kafka API supports, see Operations, resources, and protocols.
Configure ACLS for default-deny behavior
Managed Kafka clusters are configured with allow.everyone.if.no.acl.found = true
. So by default, if no ACLs are set on a resource, all principals can access the resource.
To configure a default-deny
behavior similar to that in IAM, you can first configure access for an administrator user on all resources in the cluster. As a result, every resource gets an ACL defined on it, and the allow.everyone.if.no.acl.found
behavior is suppressed. By default, any principal not explicitly allowed by an ALLOW
ACL is denied access.
For example, to set ACLs on all resources in the cluster for the service account clusterAdmin@test-project.iam.gserviceaccount.com
, create the following ACL entries.
The following gcloud CLI command grants a service account named clusterAdmin@test-project.iam.gserviceaccount.com
full administrative access (--operation=ALL
) to a specific Kafka cluster located in a particular region. This permission allows the service account to perform any operation on the cluster from any host.
gcloud managed-kafka acls add-acl-entry cluster / --principal=`User:clusterAdmin@test-project.iam.gserviceaccount.com` / --operation=ALL / --permission-type=ALLOW / --host=* / --cluster=CLUSTER_ID / --location=LOCATION
The following gcloud CLI command grants a service account named clusterAdmin@test-project.iam.gserviceaccount.com
full administrative access (--operation=ALL
) to all topics within a specific Kafka cluster located in a particular region. This permission allows the service account to perform any operation on all topics from any host.
gcloud managed-kafka acls add-acl-entry allTopics / --principal=`User:clusterAdmin@test-project.iam.gserviceaccount.com` / --operation=ALL / --permission-type=ALLOW / --host=* / --cluster=CLUSTER_ID / --location=LOCATION
The following gcloud CLI command grants a service account named clusterAdmin@test-project.iam.gserviceaccount.com
full administrative access (--operation=ALL
) to all consumer groups within a specific Kafka cluster located in a particular region. This permission allows the service account to perform any operation on all consumer groups from any host.
gcloud managed-kafka acls add-acl-entry allConsumerGroups / --principal=`User:clusterAdmin@test-project.iam.gserviceaccount.com` / --operation=ALL / --permission-type=ALLOW / --host=* / --cluster=CLUSTER_ID / --location=LOCATION
The following gcloud CLI command grants a service account named clusterAdmin@test-project.iam.gserviceaccount.com
full administrative access (--operation=ALL
) to all transactional IDs within a specific Kafka cluster located in a particular region. This permission allows the service account to perform any operation on all transactional IDs from any host.
gcloud managed-kafka acls add-acl-entry allTransactionalIds / --principal=`User:clusterAdmin@test-project.iam.gserviceaccount.com` / --operation=ALL / --permission-type=ALLOW / --host=* / --cluster=CLUSTER_ID / --location=LOCATION
The following is a list of important information about the commands:
--principal='User:test-kafka-client@test-project.iam.gserviceaccount.com'
: the principal to whom the ACL applies. The principal is a Google Cloud account, with the Kafka StandardAuthorizer prefixUser:
.--operation=all
: the Kafka operation being granted, which is full access in this case.--permission_type=ALLOW
: this ACL entry grants access.--host='*'
: the host from which the principal can access the resource.'*'
grants access from any host. Managed Service for Apache Kafka only supports ACLs with host'*'
.CLUSTER_ID: the name of your Managed Service for Apache Kafka cluster.
LOCATION: the Google Cloud region where your Managed Service for Apache Kafka cluster is located such as
us-central1
.
Configure ACLs
You can configure Apache Kafka ACLs with the Managed Service for Apache Kafka ACL APIs, or with open-source Apache Kafka tools such as Apache Kafka authorizer cli kafka-acls.sh
, or Admin Client
.
Managed Service for Apache Kafka organizes ACLs by Kafka resource patterns. The resource pattern is defined by the following:
Resource type: cluster, topic, consumer group, or transactional ID
Pattern type: literal, or prefixed (all resources whose name start with the provided string)
Resource name: the resource name or prefix to which the ACL entries apply.
A Managed Service for Apache Kafka ACL resource represents all access control configured for a single Kafka resource pattern, as a repeated list of ACL entries. The name of the ACL resource uniquely identifies the resource pattern of the ACL binding. For more information, see ACL ID.
You can manage Managed Service for Apache Kafka ACLs at the ACL resource level (all ACL entries for a resource pattern), or incrementally by adding and removing individual ACL entries for an ACL resource pattern.
For more information, see Create a Managed Kafka ACL and Add a Managed Kafka ACL entry.
Allow reading from a topic
To allow open-source Apache Kafka clients running as the service account test-kafka-client@test-project.iam.gserviceaccount.com
to read from the topic topic-name
, create a Managed Service for Apache Kafka ACL entry using the managed-kafka acls add-acl-entry
command:
gcloud managed-kafka acls add-acl-entry topic/topic-name \ --cluster=CLUSTER_ID / --location=LOCATION --principal='User:test-kafka-client@test-project.iam.gserviceaccount.com' \ --operation=READ \ --permission_type=ALLOW \ --host='*'
The following is a list of important information about the command:
topic/topic-name
: specifies the Managed Service for Apache Kafka topic to which you want to grant access. Replacetopic-name
with the actual name of your topic. Thetopic/
prefix indicates that this ACL entry applies to a specific (literal) topic resource pattern.LOCATION
: the Google Cloud region where your Managed Service for Apache Kafka cluster is located, such asus-central1
.CLUSTER_ID
: the name of your Managed Service for Apache Kafka cluster.--principal='User:test-kafka-client@test-project.iam.gserviceaccount.com'
: the principal to whom the ACL applies. The principal is a Google Cloud account, with the Kafka StandardAuthorizer prefixUser:
.--operation=READ
: the Kafka operation being granted, which isREAD
in this case.--permission_type=ALLOW
: indicates that this ACL entry grants access.--host='*'
: specifies the host from which the principal can access the resource.'*'
grants access from any host. Managed Service for Apache Kafka only supports ACLs with host'*'
.
To remove read access, you can use the remove-acl-entry
command with the same parameters.
gcloud managed-kafka acls remove-acl-entry topic/topic-name \ --cluster=CLUSTER_ID / --location=LOCATION --principal='User:test-kafka-client@test-project.iam.gserviceaccount.com' \ --operation=READ \ --permission_type=ALLOW \ --host='*'
Allow writing to all topics with a common prefix
To allow open-source Apache Kafka clients running as the service account test-kafka-client@test-project.iam.gserviceaccount.com
to write to all topics whose name starts with the prefix topic-prefix
, add a Managed Kafka ACL entry as follows:
gcloud managed-kafka acls add-acl-entry topicPrefixed/topic-prefix \ --cluster=CLUSTER_ID / --location=LOCATION --principal='User:test-kafka-client@test-project.iam.gserviceaccount.com' \ --operation=WRITE \ --permission_type=ALLOW \ --host='*'
The following is a list of important information about the command:
topicPrefixed/topic-prefix
: specifies the Managed Service for Apache Kafka resource pattern to which you want to grant access. Replacetopic-prefix
with the actual prefix of your topics. ThetopicPrefixed/
prefix indicates that this ACL entry applies to a prefixed resource pattern: all topics matching the given prefix.PROJECT
: the ID of your Google Cloud project where your Managed Service for Apache Kafka cluster is located.LOCATION
: the Google Cloud region where your Managed Service for Apache Kafka cluster is located such asus-central1
.CLUSTER_ID
: the name of your Managed Service for Apache Kafka cluster.--principal='User:test-kafka-client@test-project.iam.gserviceaccount.com'
: the principal to whom the ACL applies. The principal is a Google Cloud account, with the Kafka StandardAuthorizer prefixUser:
.--operation=WRITE
: the Kafka operation being granted, which isWRITE
in this case.--permission_type=ALLOW
: this ACL entry grants access.--host='*'
: the host from which the principal can access the resource.'*'
grants access from any host. Managed Service for Apache Kafka only supports ACLs with host'*'
.
To remove write access for this service account, remove the ACL entry:
gcloud managed-kafka acls remove-acl-entry topicPrefixed/topic-prefix \ --cluster=CLUSTER_ID / --location=LOCATION --principal='User:test-kafka-client@test-project.iam.gserviceaccount.com' \ --operation=WRITE \ --permission_type=ALLOW \ --host='*'
Deny modifying all topics
To prevent open-source Apache Kafka clients running as the service account test-kafka-client@test-project.iam.gserviceaccount.com
from modifying all topics in a cluster, you can create a Managed Service for Apache Kafka ACL resource with a list of AclEntry
resources to deny the ALTER
, ALTER_CONFIGS
, and DELETE
operations on all topics. This approach defines the required state in a single configuration.
Alternatively, you can achieve the same result by imperatively adding three separate ACL entries using the gcloud managed-kafka acls add-acl-entry
command. This method involves running the command to deny access to each of the operations ALTER
, ALTER_CONFIGS
, and DELETE
, as follows:
gcloud managed-kafka acls add-acl-entry allTopics \ --cluster=CLUSTER_ID / --location=LOCATION --principal='User:test-kafka-client@test-project.iam.gserviceaccount.com' \ --operation=ALTER \ --permission_type=DENY \ --host='*'
gcloud managed-kafka acls add-acl-entry allTopics \ --cluster=CLUSTER_ID / --location=LOCATION --principal='User:test-kafka-client@test-project.iam.gserviceaccount.com' \ --operation=ALTER_CONFIGS \ --permission_type=DENY \ --host='*'
gcloud managed-kafka acls add-acl-entry allTopics \ --cluster=CLUSTER_ID / --location=LOCATION --principal='User:test-kafka-client@test-project.iam.gserviceaccount.com' \ --operation=DELETE \ --permission_type=DENY \ --host='*'
The following information applies to each of the add-acl-entry
commands:
allTopics
: specifies that this ACL applies to all topics within the Managed Service for Apache Kafka cluster.LOCATION
: the Google Cloud region where your Managed Service for Apache Kafka cluster is located such asus-central1
.CLUSTER_ID
: the name of your Managed Service for Apache Kafka cluster.--principal='User:test-kafka-client@test-project.iam.gserviceaccount.com'
: specifies the principal to whom the ACL applies. The principal is a Google Cloud account, with the Kafka StandardAuthorizer prefixUser:
.--operation
: specifies the Kafka operation being denied:ALTER
: includes actions like changing the number of partitions or replication factor.ALTER_CONFIGS
: includes modifying topic-level configurations.DELETE
: includes deleting topics.
--permission_type=DENY
: indicates that these ACL entries block access for the specified operations.--host='*'
: specifies that this denial applies regardless of the host from which the request originates. Managed Service for Apache Kafka only supports ACLs with host'*'
.
To remove these restrictions, use the remove-acl-entry
command for each of the added entries, using the same parameters. For example, to re-allow topic deletion:
gcloud managed-kafka acls remove-acl-entry allTopics \ --cluster=CLUSTER_ID / --location=LOCATION --principal='User:test-kafka-client@test-project.iam.gserviceaccount.com' \ --operation=DELETE \ --permission_type=DENY \ --host='*'
Troubleshooting ACLs
The Apache Kafka Standard Authorizer writes audit logs by default on authorization denials. If you receive a Kafka Authorization error, you can confirm the principal, resource, and operation that was denied by searching the cluster logs for StandardAuthorizerData logAuditMessage
.
For example, here is a sample cluster log.
org.apache.kafka.metadata.authorizer.StandardAuthorizerData logAuditMessage\n INFO: Principal = User:556291496362-compute@developer.iam.gserviceaccount.com is Denied operation = DESCRIBE from host = 172.16.0.20 on resource = Topic:LITERAL:t1 for request = Metadata with resourceRefCount = 1 based on rule DefaultDeny