Companion post: From Kafka ACLs to Confluent RBAC: A Safe Migration Path with a New Open-Source Tool walks through why ACL-to-RBAC migration is harder than it looks, and the step-by-step workflow.
Why
Adopting Confluent RBAC on an existing Kafka cluster means translating every native ACL into an equivalent role binding — and the two models don’t map one-to-one. Done by hand it’s slow, easy to get subtly wrong, and hard to prove correct after the fact.
monedula-acl-rbac-converter makes that migration mechanical and reviewable.
It reads ACLs from wherever they live — a live cluster, an exported
kafka-acls.sh --list dump, JSON/YAML/CSV, Strimzi KafkaUser or Confluent
for Kubernetes manifests, a running Kubernetes cluster, or an old setup script
full of kafka-acls --add commands — and produces a Confluent RBAC role
binding plan, with every step auditable.
How it works
The production workflow is explicit and step-based, so each stage produces artifacts you can review, version, or attach to a change request:
extract -> plan -> apply (dry-run) -> apply -> verify -> delete-acls
Two operating models are supported, depending on how much you want the tool to touch:
- Direct (MDS) — apply role bindings straight to Confluent’s Metadata Service. The apply step is idempotent: existing bindings are skipped.
- Artifact-only — emit Confluent CLI scripts, Confluent for Kubernetes
manifests, or
mds-curlcommands for your own GitOps / change-control pipeline to apply, so nothing changes without a pipeline running it.
Safety is the point: plans are checksummed, effective access is verified after
apply (the new bindings really do grant what the old ACLs did), and deletion of
the source ACLs is script-based — the tool generates delete-acls.sh plus a
rollback.sh, so a human reviews and runs the cleanup deliberately.
Configure
Conversion is tuned with three optional YAML files: scopes.yaml (the
Confluent cluster IDs bindings target), rules.yaml (custom mapping
overrides), and principals.yaml (principal remapping). DENY ACLs have no RBAC
equivalent, so they aren’t silently converted — they’re reported and handled
separately.