Access Control Lists (ACL): Mengelola Otorisasi di Apache Kafka #
Setelah kita berhasil mengotentikasi klien menggunakan mTLS atau SASL, langkah berikutnya adalah membatasi apa saja yang dapat dilakukan oleh klien tersebut di dalam kluster Kafka kita. Tanpa pembatasan akses (authorization), klien yang berhasil masuk dapat dengan bebas membaca data sensitif milik tim lain, mempublikasikan pesan sampah ke topik keuangan, atau bahkan menghapus topik penting secara tidak sengaja.
Di Apache Kafka, otorisasi dikelola secara bawaan menggunakan Access Control Lists (ACL). ACL bertindak sebagai matriks kebijakan keamanan yang mendefinisikan secara tepat “Siapa” yang boleh melakukan “Tindakan Apa” terhadap “Sumber Daya Mana” dari “Host Mana”.
Artikel ini akan mengupas tuntas struktur pembentuk aturan ACL di Kafka, cara mengaktifkan kebijakan keamanan Zero-Trust (Deny-by-Default), panduan praktis pengelolaan ACL menggunakan alat baris perintah CLI kafka-acls.sh untuk produser, konsumen, dan transaksi, serta logika prioritas evaluasi aturan ACL di broker.
Membedah Struktur Kebijakan ACL Kafka #
Satu aturan ACL di Apache Kafka didefinisikan secara deklaratif menggunakan enam komponen pembentuk utama. Mari kita bedah komponen-komponen tersebut:
+-----------------------------------------------------------------------------+
| SATU ENTRI ATURAN ACL |
| |
| 1. PRINCIPAL : Siapa penggunanya? (misal, User:payment-service) |
| 2. HOST : Dari mana koneksinya? (misal, 192.168.1.50 atau *) |
| 3. OPERATION : Tindakan apa? (misal, Read, Write, Describe) |
| 4. RESOURCE TYPE: Apa jenis targetnya? (misal, Topic, Group) |
| 5. PATTERN TYPE : Bagaimana mencocokkan nama? (Literal vs Prefixed) |
| 6. PERMISSION : Diizinkan atau dilarang? (Allow vs Deny) |
+-----------------------------------------------------------------------------+
1. Principal (Identitas Pengguna) #
Merupakan nama pengguna yang telah terverifikasi saat fase otentikasi. Format penulisannya adalah Type:Name (misal: User:payment-service atau User:CN=producer-app,O=Corp jika menggunakan mTLS tanpa mapping). Kita dapat menggunakan wildcard User:* untuk menerapkan aturan kepada semua pengguna terdaftar.
2. Host (Alamat Asal Koneksi) #
Membatasi dari mana alamat IP klien aturan ini berlaku. Hal ini sangat berguna untuk membatasi agar aplikasi kritis hanya dapat diakses dari segmen jaringan tertentu (misal: 192.168.10.50). Jika kita tidak ingin membatasi berdasarkan IP fisik, kita dapat menyetelnya ke wildcard * (artinya dari host mana saja).
3. Resource Type (Jenis Sumber Daya) #
Menentukan kategori aset di dalam Kafka yang ingin diamankan. Kategori yang umum digunakan antara lain:
- Topic: Topik Kafka tempat data disimpan.
- Group: ID Consumer Group yang digunakan untuk melacak offset pembacaan konsumen.
- Cluster: Mewakili kluster Kafka itu sendiri (digunakan untuk tindakan administratif seperti membuat topik atau memantau metrik internal).
- TransactionalId: ID yang digunakan oleh produser transaksional untuk menjamin Exactly-Once Semantics.
4. Pattern Type (Metode Pencocokan Nama) #
Menentukan bagaimana Kafka mencocokkan string nama resource yang kita definisikan dengan resource riil di kluster:
- Literal: Nama harus sama persis (misal: aturan untuk topik
finance-transactionshanya berlaku untuk topik tersebut). - Prefixed: Aturan berlaku untuk semua resource yang diawali dengan string tertentu (misal: prefiks
dept-sales-akan mencakup topikdept-sales-invoice,dept-sales-leads, dll). - Wildcard (
*): Berlaku untuk seluruh resource dengan tipe tersebut.
5. Operation (Tindakan/Aksi) #
Mendefinisikan operasi spesifik yang diizinkan atau dilarang. Contoh operasi meliputi:
ReaddanWrite(untuk membaca/menulis data).Describe(untuk melihat metadata topik, seperti jumlah partisi).CreatedanDelete(untuk membuat/menghapus topik).Alter(untuk mengubah konfigurasi topik).All(mencakup seluruh operasi di atas).
6. Permission Type (Jenis Izin) #
Hanya memiliki dua nilai: Allow (mengizinkan akses) atau Deny (melarang akses secara mutlak).
Mengaktifkan Kebijakan Zero-Trust: Deny-by-Default #
Secara default, jika kita baru mengaktifkan modul otorisasi di Kafka, broker memiliki parameter bawaan allow.everyone.if.no.acl.found=true. Artinya, jika suatu topik tidak memiliki aturan ACL sama sekali, maka semua klien (termasuk pengguna anonim) diizinkan untuk mengakses topik tersebut. Ini tentu bukan praktik keamanan yang baik untuk produksi.
Kita harus menerapkan kebijakan Zero-Trust (Deny-by-Default), di mana semua akses ditolak kecuali telah diizinkan secara eksplisit oleh ACL.
Konfigurasi Broker (server.properties)
#
Untuk mengaktifkannya di lingkungan kluster berbasis KRaft (Kafka 3.x+), tambahkan baris berikut di konfigurasi broker:
# Mengaktifkan Standard Authorizer bawaan KRaft
authorizer.class.name=org.apache.kafka.metadata.authorizer.StandardAuthorizer
# Mengunci kluster: Jika tidak ada ACL, akses ditolak secara mutlak
allow.everyone.if.no.acl.found=false
# Mendaftarkan pengguna admin kluster (super users) yang kebal terhadap aturan ACL
# (Super users selalu memiliki akses penuh untuk seluruh operasi administratif)
super.users=User:admin;User:kafka-broker
Catatan: Jika kluster Anda masih menggunakan ZooKeeper, ganti kelas authorizer menjadi kafka.security.authorizer.AclAuthorizer.
Panduan Praktis Pengelolaan ACL dengan CLI kafka-acls.sh
#
Kafka menyediakan alat baris perintah bernama kafka-acls.sh untuk memanipulasi entri ACL langsung di metadata cluster.
Berikut adalah skenario operasional yang sering ditemui di lingkungan produksi beserta perintah eksekusi CLI-nya:
flowchart TD
subgraph ClientApps ["Aplikasi Klien"]
Prod["Producer App (User: payment-prod)"]
Cons["Consumer App (User: payment-cons)"]
end
subgraph KafkaBroker ["Kafka Broker (ACL Rules)"]
StandardAuth{"Standard Authorizer"}
Rule1["ACL Allow Write/Describe on Topic 'payment-logs'"]
Rule2["ACL Allow Read/Describe on Topic 'payment-logs'"]
Rule3["ACL Allow Read on Group 'payment-group'"]
StandardAuth --> Rule1 & Rule2 & Rule3
end
Prod -->|1. Write Record| StandardAuth
Cons -->|2. Read Record| StandardAuth
Rule1 -.->|Allow payment-prod| Prod
Rule2 -.->|Allow payment-cons| Cons
Rule3 -.->|Allow Group Access| Cons
1. Konfigurasi ACL untuk Produser Standar #
Produser membutuhkan izin Write dan Describe pada nama topik target agar dapat mengirimkan pesan dan membaca metadata partisi.
kafka-acls.sh --bootstrap-server localhost:9093 \
--command-config client-ssl.properties \
--add \
--allow-principal User:payment-prod \
--operation Write \
--operation Describe \
--topic payment-logs \
--resource-pattern-type literal
2. Konfigurasi ACL untuk Konsumen Standar #
Konsumen membutuhkan izin Read dan Describe pada topik, serta izin Read pada consumer group ID yang digunakan untuk menyimpan offset.
# Memberikan izin membaca topik 'payment-logs'
kafka-acls.sh --bootstrap-server localhost:9093 \
--command-config client-ssl.properties \
--add \
--allow-principal User:payment-cons \
--operation Read \
--operation Describe \
--topic payment-logs \
--resource-pattern-type literal
# Memberikan izin bergabung ke Consumer Group 'payment-analytics-group'
kafka-acls.sh --bootstrap-server localhost:9093 \
--command-config client-ssl.properties \
--add \
--allow-principal User:payment-cons \
--operation Read \
--group payment-analytics-group \
--resource-pattern-type literal
3. Konfigurasi ACL untuk Produser Transaksional (Exactly-Once Semantics) #
Produser transaksional membutuhkan otorisasi tambahan pada TransactionalId yang digunakannya agar broker dapat memverifikasi transaksi yang aman.
kafka-acls.sh --bootstrap-server localhost:9093 \
--command-config client-ssl.properties \
--add \
--allow-principal User:payment-prod-tx \
--operation Write \
--operation Describe \
--transactional-id tx-payment- \
--resource-pattern-type prefixed
Catatan: Penggunaan --resource-pattern-type prefixed di atas memungkinkan produser transaksional menggunakan ID transaksi apa saja yang diawali dengan tx-payment- (seperti tx-payment-001, tx-payment-002) tanpa perlu membuat ACL baru untuk setiap ID transaksi.
4. Konfigurasi ACL untuk Tugas Administratif (Admin Tasks) #
Tim operasi data (data ops) sering kali perlu melakukan pemeliharaan kluster seperti menambah partisi, melakukan penyeimbangan partisi (partition reassignment), atau memantau metrik kluster tanpa menjadi super.users penuh demi mematuhi prinsip hak akses terendah (principle of least privilege).
Untuk menjalankan perintah tersebut, user admin membutuhkan izin pada resource Cluster tingkat tinggi:
# Memberikan izin administratif kepada user 'ops-engineer'
# untuk mengubah konfigurasi kluster dan melakukan rebalancing partisi
kafka-acls.sh --bootstrap-server localhost:9093 \
--command-config client-ssl.properties \
--add \
--allow-principal User:ops-engineer \
--operation Alter \
--operation ClusterAction \
--operation Describe \
--cluster
--cluster: Menandakan bahwa target resource adalah tingkat kluster global (bernamakafka-cluster).ClusterAction: Hak khusus untuk melakukan perintah penyeimbangan replika dan pemantauan inter-broker quorum.Alter: Mengizinkan manipulasi konfigurasi broker secara dinamis di runtime.
5. Menghapus Aturan ACL #
Jika sebuah aplikasi didekomisi, kita harus menghapus aturan ACL-nya demi menjaga kebersihan metadata kluster.
kafka-acls.sh --bootstrap-server localhost:9093 \
--command-config client-ssl.properties \
--remove \
--allow-principal User:payment-prod \
--operation Write \
--topic payment-logs \
--force
Logika Evaluasi ACL di Broker (Precedence Rules) #
Ketika sebuah klien mengirimkan request ke broker Kafka (misal, request untuk menulis pesan), Broker Authorizer akan mengevaluasi daftar ACL yang ada untuk mengambil keputusan: Allow atau Deny.
Logika evaluasi ini berjalan mengikuti aturan prioritas berikut secara ketat:
flowchart TD
A["Klien Mengirim Request"] --> B{"Apakah Principal adalah SuperUser?"}
B -- "YA" --> ALLOW1["ALLOW"]
B -- "TIDAK" --> C{"Apakah ada aturan DENY yang cocok?"}
C -- "YA" --> DENY1["DENY (Mutlak)"]
C -- "TIDAK" --> D{"Apakah ada aturan ALLOW yang cocok?"}
D -- "YA" --> ALLOW2["ALLOW"]
D -- "TIDAK" --> E["Tolak Akses (Default)"] --> DENY2["DENY"]
Tiga Aturan Emas Evaluasi ACL: #
- Super Users Selalu Lolos: Jika pengguna terdaftar di parameter
super.usersbroker, proses otorisasi langsung selesai dengan keputusan Allow, mengabaikan seluruh aturan ACL lainnya. - Deny Mengalahkan Allow (Deny Precedence): Jika ada aturan
Denykhusus yang cocok dengan principal, host, dan operasi klien, maka akses akan langsung ditolak (Deny), meskipun pada saat yang sama ada aturanAllowyang mengizinkannya. - Pencocokan Literal Mengalahkan Prefixed: Saat mencari aturan yang cocok, pencocokan nama yang bersifat persis (Literal) akan dievaluasi terlebih dahulu sebelum beralih ke pencocokan awalan (Prefixed), dan terakhir mencocokkan wildcard
*.
Audit & Diagnostik Kesalahan Otorisasi ACL #
Dalam operasional sehari-hari, kesalahan konfigurasi ACL sering kali memicu error di sisi aplikasi klien. Tanpa log yang jelas, tim developer akan kesulitan mengetahui apakah kegagalan koneksi disebabkan oleh masalah jaringan, kesalahan otentikasi (salah password), atau kegagalan otorisasi (ACL belum didaftarkan).
1. Mengaktifkan Audit Logging Otorisasi di Broker #
Secara default, broker Kafka memisahkan log otorisasi ke berkas khusus bernama kafka-authorizer.log agar tidak membanjiri log utama (server.log). Kita dapat mengonfigurasi tingkat kerincian log ini melalui berkas log4j.properties pada setiap broker:
# Memisahkan log otorisasi ke appender khusus
log4j.logger.kafka.authorizer.logger=INFO, authorizerAppender
log4j.additivity.kafka.authorizer.logger=false
# Mengatur file rolling harian untuk log otorisasi
log4j.appender.authorizerAppender=org.apache.log4j.DailyRollingFileAppender
log4j.appender.authorizerAppender.File=${kafka.logs.dir}/kafka-authorizer.log
log4j.appender.authorizerAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.authorizerAppender.layout.ConversionPattern=[%d] %p %m (%c)%n
2. Membaca Baris Log Kegagalan Otorisasi #
Ketika ada klien yang ditolak aksesnya, berkas kafka-authorizer.log akan mencatat baris entri seperti berikut:
[2026-06-08 20:42:00,123] INFO Principal = User:payment-cons is Denied Operation = Read from Host = 192.168.1.50 on Resource = Topic:LITERAL:payment-logs (kafka.authorizer.logger)
Pembedahan Entri Log:
Principal = User:payment-cons: Identitas klien yang terdeteksi.is Denied: Keputusan final dari authorizer (ditolak).Operation = Read: Jenis tindakan yang dicoba oleh klien (membaca data).Host = 192.168.1.50: IP fisik dari server aplikasi klien.Resource = Topic:LITERAL:payment-logs: Aset target berupa topik bernamapayment-logsdengan pencocokan nama persis (literal).
Dengan membaca log ini, administrator kluster dapat dengan cepat mengidentifikasi bahwa user payment-cons membutuhkan ACL baru untuk operasi Read pada topik payment-logs.
3. Pengecualian (Exceptions) pada Client SDK #
Di sisi aplikasi klien Java, kegagalan otorisasi akan dilemparkan sebagai kelas pengecualian (exception) spesifik:
TopicAuthorizationException: Dilemparkan saat produser mencoba melakukansend()ke topik yang tidak memiliki izinWrite, atau konsumen mencoba melakukanpoll()dari topik tanpa izinRead.GroupAuthorizationException: Dilemparkan saat konsumen mencoba bergabung ke dalam Consumer Group (misal: saat inisialisasi) tetapi pengguna tersebut tidak memiliki izinReadpada resourceGroupuntuk group ID yang bersangkutan.ClusterAuthorizationException: Terjadi ketika aplikasi mencoba melakukan operasi administratif (seperti membuat topik melaluiAdminClientatau melakukan perubahan konfigurasi) tanpa memiliki izin administratif tingkat kluster (Clusterresource).
Ringkasan #
- Otorisasi ACL — Gerbang penentu tindakan klien. Wajib dikonfigurasi setelah otentikasi diaktifkan agar kluster terlindungi secara granular.
- Zero-Trust — Setel
allow.everyone.if.no.acl.found=falsedi broker produksi agar semua akses ditolak secara default kecuali ada izin sah.- Prefixed Patterns — Manfaatkan pencocokan awalan (
prefixed) untuk meminimalkan jumlah entri ACL pada topik atau ID transaksi yang memiliki pola nama terstandar.- Deny Precedence — Deny bersifat mutlak. Jika klien terkena satu aturan
Deny, ia tidak akan bisa mengakses resource meskipun memiliki aturanAllow.- Consumer Group Auth — Ingat bahwa konsumen tidak hanya butuh akses
Readpada Topik, tetapi juga butuh aksesReadpadaGroupagar tidak memicu errorGroupAuthorizationException.
← Sebelumnya: Client Authentication Berikutnya: Top-Level Security →