このドキュメントでは、Google Cloud Managed Service for Apache Kafka でアクセス制御に Apache Kafka アクセス制御リスト(ACL)を使用する方法について説明します。
Apache Kafka ACL は、Kafka クラスタ内で詳細なアクセス制御を提供します。Managed Service for Apache Kafka では、すぐに使用できる StandardAuthorizer が有効になっています。これは、KRaft ベースの Kafka クラスタ メタデータに ACL を保存します。
これらの ACL は、認証されたユーザーが特定の Kafka リソースに対して実行できる特定のオペレーション(トピックでのメッセージの生成や消費など)を制御します。
これらの ACL は、標準の Apache Kafka クライアントを使用してクラスタとのやり取りを制御する場合に便利です。標準の Apache Kafka クライアントは、最初の接続時にクラスタレベルの IAM チェックのみを受けます。詳しくは、IAM によるアクセス制御をご覧ください。
Kafka ACL アクセス制御の仕組み
クライアントは、クラスタ内の Kafka の標準 ACL 認可ツールとやり取りします。承認者は、関連する Apache Kafka ACL を評価して、プリンシパルからリクエストされた特定のオペレーション(トピックへの書き込みやグループからの読み取りなど)を承認します。ACL チェックに使用されるプリンシパルは、次のいずれかの認証方法から派生します。
SASL: サービス アカウントのメールなどの IAM プリンシパル。
mTLS: クライアント証明書の識別名(DN)。プリンシパル マッピング ルールによって変換される可能性があります。
包括的なセキュリティを確保するには、次の構成を行う必要があります。
管理アクセス用の IAM 権限。詳しくは、IAM によるアクセス制御をご覧ください。
認証方法に関係なく、オープンソースの Apache Kafka クライアントからのクラスタ内データ アクセスとオペレーション用の Kafka ACL。
Apache Kafka ACL の使用
Apache Kafka ACL バインディングの形式は次のとおりです。
Principal P is [Allowed/Denied] Operation O From Host H on any resource matching Resource Pattern RP.
形式に関する重要な情報を次に示します。
プリンシパル(P): 承認されるユーザー ID。接頭辞
User:が付いています。SASL 認証の場合、これは
User:my-service-account@my-project.iam.gserviceaccount.comなどの IAM プリンシパルです。mTLS 認証の場合、これはクライアント証明書の識別名(DN)(
User:CN=my-client,OU=my-org-unitなど)です。正確な形式は、証明書のサブジェクトによって異なります。プリンシパル マッピング ルールを使用して、この値を変換できます。
権限タイプ(許可/拒否): ACL バインディングがアクセスを許可するか拒否するか。拒否バインディングが優先されます。
Operation(O): 実行されたアクション(読み取り、書き込み、作成など)。さまざまな Kafka プロトコルでどのオペレーションがどのリソースに適用されるかについては、Apache Kafka ドキュメントのプロトコルのオペレーションとリソースをご覧ください。
ホスト(H): リクエストの送信元マシン。Managed Service for Apache Kafka はクライアント ネットワーク アドレスを変換するため、
'*'以外のホストの使用はサポートされていません。リソース パターン(RP): 特定のリソースを照合するために使用されるパターン。リソース パターンは、リソースタイプ、リソース名、パターン タイプ(
LITERALまたはPREFIXED)で構成されます。
デフォルトのアクセス権
Managed Service for Apache Kafka クラスタは、Apache Kafka プロパティ allow.everyone.if.no.acl.found が true に設定された状態で動作します。Kafka ACL の有無は、リソースへのアクセスレベルを直接決定します。
トピックなどの特定のリソースに対して Kafka ACL が定義されていない場合、認証されたすべてのプリンシパルにそのリソースへのアクセス権が付与されます。この構成により、ACL を構成しなくても、Managed Service for Apache Kafka クラスタをすぐに運用できます。
リソースの Kafka ACL を定義すると、すぐにアクセスが制限されます。Kafka ACL の
ALLOWエントリを使用して明示的に権限が付与されたプリンシパルのみが、一致するリソースにアクセスできます(DENYエントリによって明示的にブロックされていない場合)。
Managed Service for Apache Kafka は、クラスタに対する管理者権限をサービス エージェントに付与します。このアクセスにより、サービス エージェントは、クラスタで構成されている他の ACL に関係なく、Managed Service for Apache Kafka API によってリクエストされたオペレーションを実行できます。Managed Service for Apache Kafka は、StandardAuthorizer 実装を変更することでこれを実現します。この変更により、サービス エージェントには読み取りと書き込みのオペレーションを除く、スーパー ユーザーと同様の権限が付与されます。この構成は変更できません。
Kafka プリンシパル
Managed Service for Apache Kafka クラスタの Kafka プリンシパルは、Kafka StandardAuthorizer 接頭辞 "User:" で指定されます。
SASL/IAM の場合: プリンシパルはGoogle Cloud アカウントです。たとえば、サービス アカウント
test-kafka-client@test-project.iam.gserviceaccount.comへのアクセス権を付与するには、Kafka プリンシパル"User:test-kafka-client@test-project.iam.gserviceaccount.com"を使用します。Kafka ACL プリンシパルは、グループやプリンシパル セットではなく、ユーザー、サービス アカウント、個々の IAM プリンシパルを指定する必要があります。Kafka ACL は、 Google Cloud プリンシパルのグループ メンバーシップの解決をサポートしていません。mTLS の場合: プリンシパルは、クライアント証明書のサブジェクトの識別名(DN)から取得されます。例:
User:CN=client1,OU=dev,O=MyOrg,L=City,ST=State,C=USmTLS プリンシパル マッピング ルールを使用すると、DN を ACL 用のユーザー フレンドリーなプリンシパル文字列に変換できます。
Google グループまたはプリンシパル セットのすべてのメンバーに適用される ACL を作成するには、プロキシ サービス アカウント プリンシパルとサービス アカウントの権限借用を使用します。
グループのプロキシとして使用するサービス アカウントを作成します。
Google グループまたはプリンシパル セットに、サービス アカウントに対するサービス アカウント トークン作成者ロールを付与します。サービス アカウントに対するアクセス権の管理をご覧ください。
プロキシ サービス アカウントの Kafka ACL を追加します。プリンシパルの例:
User:group-proxy@test-project.iam.gserviceaccount.com。Kafka クライアントでサービス アカウントの権限借用を使用して、サービス アカウントとして Kafka に対する認証を行います。 Google Cloud IAM は、プロキシ サービス アカウントの権限借用が許可されているグループのメンバーとして個々のプリンシパルを承認します。Kafka は、クラスタ内の既存の ACL に対してプロキシ サービス アカウントを承認します。
プロデューサーとコンシューマーの Kafka オペレーション
オペレーションは、リソースに対して実行されるアクションです。リソースごとに、オペレーションがそのリソースの 1 つ以上の Kafka プロトコル リクエストにマッピングされます。たとえば、topic リソースタイプの READ オペレーションは、Fetch、OffsetCommit、TxnOffsetCommit の Apache Kafka プロトコルにマッピングされます。
トピックに対するプリンシパル プロデューサーのアクセス権を付与する手順は次のとおりです。
トピック リソースで、
WRITEオペレーションとCREATEオペレーションを許可します。トランザクション ID を使用する場合は、トランザクション ID リソースで
WRITEオペレーションを許可します。
プリンシパル コンシューマーにトピックへのアクセス権を付与する手順は次のとおりです。
トピック リソースで
READオペレーションを許可します。コンシューマー グループ リソースで
READオペレーションを許可します。
Kafka API がサポートするリソースに対する有効なオペレーションの詳細については、Apache Kafka ドキュメントのプロトコルのオペレーションとリソースをご覧ください。
デフォルト拒否動作の ACL を構成する
マネージド Kafka クラスタは allow.everyone.if.no.acl.found = true で構成されます。したがって、デフォルトでは、リソースに ACL が設定されていない場合、すべてのプリンシパルがリソースにアクセスできます。
IAM と同様の default-deny 動作を構成するには、まずクラスタ内のすべてのリソースに対する管理者ユーザーのアクセス権を構成します。その結果、すべてのリソースに ACL が定義され、allow.everyone.if.no.acl.found の動作が抑制されます。デフォルトでは、ALLOW ACL で明示的に許可されていないプリンシパルはアクセスを拒否されます。
たとえば、サービス アカウント clusterAdmin@test-project.iam.gserviceaccount.com のクラスタ内のすべてのリソースに ACL を設定するには、次の ACL エントリを作成します。
次の gcloud CLI コマンドは、特定のリージョンにある特定の Kafka クラスタに対する完全な管理者アクセス権(--operation=ALL)を clusterAdmin@test-project.iam.gserviceaccount.com というサービス アカウントに付与します。この権限により、サービス アカウントは任意のホストからクラスタに対して任意のオペレーションを実行できます。
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
次の gcloud CLI コマンドは、特定のリージョンにある特定の Kafka クラスタ内のすべてのトピックに対する完全な管理アクセス権(--operation=ALL)を clusterAdmin@test-project.iam.gserviceaccount.com という名前のサービス アカウントに付与します。この権限により、サービス アカウントは任意のホストからすべてのトピックに対して任意のオペレーションを実行できます。
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
次の gcloud CLI コマンドは、特定のリージョンにある特定の Kafka クラスタ内のすべてのコンシューマー グループに対する完全な管理者アクセス権(--operation=ALL)を clusterAdmin@test-project.iam.gserviceaccount.com という名前のサービス アカウントに付与します。この権限により、サービス アカウントは任意のホストからすべてのコンシューマー グループに対して任意のオペレーションを実行できます。
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
次の gcloud CLI コマンドは、特定のリージョンにある特定の Kafka クラスタ内のすべてのトランザクション ID に対する完全な管理者アクセス権(--operation=ALL)を clusterAdmin@test-project.iam.gserviceaccount.com という名前のサービス アカウントに付与します。この権限により、サービス アカウントは任意のホストからすべてのトランザクション ID に対して任意のオペレーションを実行できます。
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
コマンドに関する重要な情報を次に示します。
--principal='User:test-kafka-client@test-project.iam.gserviceaccount.com': ACL が適用されるプリンシパル。プリンシパルはGoogle Cloud アカウントで、Kafka StandardAuthorizer の接頭辞User:が付いています。--operation=all: 許可される Kafka オペレーション(この場合はフルアクセス)。--permission-type=ALLOW: この ACL エントリはアクセス権を付与します。--host='*': プリンシパルがリソースにアクセスできるホスト。'*'は、任意のホストからのアクセスを許可します。Managed Service for Apache Kafka は、ホスト'*'を含む ACL のみをサポートします。CLUSTER_ID: Managed Service for Apache Kafka クラスタの名前。
LOCATION: Managed Service for Apache Kafka クラスタが配置されている Google Cloud リージョン(
us-central1など)。
ACL を構成する
Apache Kafka ACL は、Managed Service for Apache Kafka ACL API を使用して構成するか、Apache Kafka authorizer cli kafka-acls.sh や Admin Client などのオープンソースの Apache Kafka ツールを使用して構成できます。
Managed Service for Apache Kafka は、Kafka リソース パターンで ACL を整理します。リソース パターンは次のように定義されます。
リソースタイプ: クラスタ、トピック、コンシューマー グループ、トランザクション ID
パターン タイプ: リテラル、または接頭辞(指定された文字列で始まる名前を持つすべてのリソース)
リソース名: ACL エントリが適用されるリソース名または接頭辞。
Managed Service for Apache Kafka ACL リソースは、単一の Kafka リソース パターン用に構成されたすべてのアクセス制御を、ACL エントリの繰り返しリストとして表します。ACL リソースの名前は、ACL バインディングのリソース パターンを一意に識別します。詳細については、ACL ID をご覧ください。
Managed Service for Apache Kafka ACL は、ACL リソースレベル(リソース パターンのすべての ACL エントリ)で管理することも、ACL リソース パターンの個々の ACL エントリを追加または削除して増分的に管理することもできます。
詳細については、マネージド Kafka ACL を作成するとマネージド Kafka ACL エントリを追加するをご覧ください。
トピックからの読み取りを許可する
サービス アカウント test-kafka-client@test-project.iam.gserviceaccount.com として実行されているオープンソースの Apache Kafka クライアントがトピック topic-name から読み取れるようにするには、managed-kafka acls add-acl-entry コマンドを使用して Managed Service for Apache Kafka ACL エントリを作成します。
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='*'
コマンドに関する重要な情報を次に示します。
topic/topic-name: アクセス権を付与する Managed Service for Apache Kafka トピックを指定します。topic-nameは、トピックの実際の名前に置き換えます。topic/接頭辞は、この ACL エントリが特定のリテラル トピック リソース パターンに適用されることを示します。LOCATION: Managed Service for Apache Kafka クラスタが配置されている Google Cloud リージョン(us-central1など)。CLUSTER_ID: Managed Service for Apache Kafka クラスタの名前。--principal='User:test-kafka-client@test-project.iam.gserviceaccount.com': ACL が適用されるプリンシパル。プリンシパルはGoogle Cloud アカウントで、Kafka StandardAuthorizer の接頭辞User:が付いています。--operation=READ: 許可される Kafka オペレーション(この場合はREAD)。--permission-type=ALLOW: この ACL エントリがアクセス権を付与することを示します。--host='*': プリンシパルがリソースにアクセスできるホストを指定します。'*'は、任意のホストからのアクセスを許可します。Managed Service for Apache Kafka は、ホスト'*'を含む ACL のみをサポートします。
読み取りアクセス権を削除するには、同じパラメータを使用して remove-acl-entry コマンドを使用します。
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='*'
共通の接頭辞を持つすべてのトピックへの書き込みを許可する
サービス アカウント test-kafka-client@test-project.iam.gserviceaccount.com として実行されているオープンソースの Apache Kafka クライアントが、プレフィックス topic-prefix で始まる名前のすべてのトピックに書き込めるようにするには、次のように Managed Kafka ACL エントリを追加します。
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='*'
コマンドに関する重要な情報を次に示します。
topicPrefixed/topic-prefix: アクセス権を付与する Managed Service for Apache Kafka リソース パターンを指定します。topic-prefixは、トピックの実際の接頭辞に置き換えます。topicPrefixed/プレフィックスは、この ACL エントリがプレフィックス付きのリソース パターン(指定されたプレフィックスに一致するすべてのトピック)に適用されることを示します。PROJECT: Managed Service for Apache Kafka クラスタが配置されている Google Cloud プロジェクトの ID。LOCATION: Managed Service for Apache Kafka クラスタが配置されている Google Cloud リージョン(us-central1など)。CLUSTER_ID: Managed Service for Apache Kafka クラスタの名前。--principal='User:test-kafka-client@test-project.iam.gserviceaccount.com': ACL が適用されるプリンシパル。プリンシパルはGoogle Cloud アカウントで、Kafka StandardAuthorizer の接頭辞User:が付いています。--operation=WRITE: 許可される Kafka オペレーション(この場合はWRITE)。--permission-type=ALLOW: この ACL エントリはアクセス権を付与します。--host='*': プリンシパルがリソースにアクセスできるホスト。'*'は、任意のホストからのアクセスを許可します。Managed Service for Apache Kafka は、ホスト'*'を含む ACL のみをサポートします。
このサービス アカウントの書き込みアクセス権を削除するには、ACL エントリを削除します。
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='*'
すべてのトピックの変更を拒否する
サービス アカウント test-kafka-client@test-project.iam.gserviceaccount.com として実行されているオープンソースの Apache Kafka クライアントがクラスタ内のすべてのトピックを変更しないようにするには、AclEntry リストを含む Managed Service for Apache Kafka ACL リソースを作成して、すべてのトピックに対する ALTER、ALTER_CONFIGS、DELETE オペレーションを拒否します。このアプローチでは、必要な状態を単一の構成で定義します。
または、gcloud managed-kafka acls add-acl-entry コマンドを使用して 3 つの個別の ACL エントリを命令的に追加することで、同じ結果を得ることもできます。この方法では、次のコマンドを実行して、ALTER、ALTER_CONFIGS、DELETE の各オペレーションへのアクセスを拒否します。
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='*'
次の情報は、各 add-acl-entry コマンドに適用されます。
allTopics: この ACL が Managed Service for Apache Kafka クラスタ内のすべてのトピックに適用されることを指定します。LOCATION: Managed Service for Apache Kafka クラスタが配置されている Google Cloud リージョン(us-central1など)。CLUSTER_ID: Managed Service for Apache Kafka クラスタの名前。--principal='User:test-kafka-client@test-project.iam.gserviceaccount.com': ACL が適用されるプリンシパルを指定します。プリンシパルは、KafkaStandardAuthorizer接頭辞User:を持つGoogle Cloud アカウントです。--operation: 拒否されている Kafka オペレーションを指定します。ALTER: パーティション数やレプリケーション係数の変更などのアクションが含まれます。ALTER_CONFIGS: トピック レベルの構成の変更が含まれます。DELETE: トピックの削除が含まれます。
--permission-type=DENY: これらの ACL エントリが、指定されたオペレーションのアクセスをブロックすることを示します。--host='*': リクエストの送信元ホストに関係なく、この拒否が適用されることを指定します。Managed Service for Apache Kafka は、ホスト'*'を含む ACL のみをサポートします。
これらの制限を削除するには、追加したエントリごとに同じパラメータを使用して remove-acl-entry コマンドを使用します。たとえば、トピックの削除を再度許可するには、次の操作を行います。
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='*'
ACL のトラブルシューティング
Apache Kafka Standard Authorizer は、デフォルトで認可拒否時に監査ログを書き込みます。Kafka 認証エラーが表示された場合は、クラスタログで StandardAuthorizerData logAuditMessage を検索して、拒否されたプリンシパル、リソース、オペレーションを確認できます。
たとえば、クラスタログのサンプルを次に示します。
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