monedula-acl-rbac-converter docs menu
Safety guarantees
The guarantees monedula-acl-rbac makes: no mutation without confirmation, script-only deletion, no dropped ACLs, no widened scope, stale plans refused.
On this page
A permission that disappears breaks production; one that grows too wide opens it. Each guarantee below is enforced by the tool and closes one way for either to happen silently.
Nothing changes without confirmation
A command that changes external state does nothing unless you pass --confirm or type yes at an interactive prompt. Outside a terminal, --confirm is the only way. apply --dry-run is the explicit preview: it reads MDS, records every call it would make and writes nothing. Every other command only reads, or writes local files such as the run directory’s artifacts.
Deletion happens only through scripts
The tool never runs a destructive Kafka call itself. delete-acls and delete-deny-acls write a script that you can read, edit or abandon, and the matching rollback script at the same time; to automate deletion, your pipeline runs the generated script after review. delete-acls also needs --i-understand-this-is-destructive before it writes anything.
apply only creates role bindings, and the tool never deletes or modifies them: you roll back apply with the Confluent CLI or the MDS API, as Recover from a failed run shows.
No ACL is silently dropped
Every input ACL appears in exactly one list of the plan, bindings, unmapped or rejected, with a reason for each one not converted (How ACLs map to RBAC roles). plan exits 3 until you resolve or accept the unconverted ones, and a role that does not grant every operation of its source ACLs raises a PARTIAL_RULE_COVERAGE warning.
Scope is never widened
A binding keeps the resource pattern of the ACLs it replaces, as the mapping rules describe. An ACL that could only be converted by widening it, such as one limited to a host, is left unmapped instead.
Stale plans are refused
Every artifact that later steps trust is fingerprinted:
planwritesplan.json.sha256next toplan.json.apply,verify,delete-aclsanddelete-deny-aclscheck it and refuse a plan that changed since, with exit code 5.- The generated deletion scripts hash
plan.jsonagain when they run, and refuse to run on a mismatch. They fail closed: ifplan.jsoncannot be hashed at all, because neithersha256sumnorshasumexists or the file is not readable there, they refuse too. The only escape hatch isMONEDULA_SKIP_PLAN_HASH_CHECK=1, for a script you run on purpose where its run directory is not present, such as inside a broker container. planstamps the SHA-256 ofacls.jsoninto the plan. The delete commands select the ACLs to remove fromacls.jsonbyid, so they refuse anacls.jsonthat changed after planning.verifystamps the plan’s SHA-256 intoverify.json. The delete commands refuse averify.jsonthat checked a different plan, so an old verification cannot vouch for a regenerated plan: after a plan change, apply and verify again.
To apply a plan you edited by hand, plan --revalidate checks its structure and refreshes the checksum. It does not run the mapping or the DENY analysis again, so the new checksum vouches only for the plan you reviewed (Plan and review role bindings).
Effective access, verified before deletion
By default, verify asks MDS, for each source ACL, whether the original access is now granted, so a binding that exists but grants nothing shows up as EFFECTIVE_MISSING (Verify effective access).
delete-acls only deletes source ACLs whose result is EFFECTIVE_OK, or BINDING_EXISTS when verify.json comes from --mode bindings-exist, which only checks that the binding rows exist. Results that MDS could not answer, EFFECTIVE_UNKNOWN, block deletion too, unless you ran verify --accept-unknown-verify for an MDS that lacks the lookup endpoint. That override is opt-in, recorded in the detail field of every result it changed, and never weakens the block on EFFECTIVE_MISSING.
DENY ACLs get extra care
DENY ACLs are never converted. Removing one can grant access, so it takes a separate command, delete-deny-acls, which needs --i-understand-this-may-grant-access and a target principal, and refuses unless every verify result is confirmed. Its script checks each DENY against MDS again at the moment it runs, and skips a DENY whose removal would now grant access, with no override. DENY ACLs for a wildcard principal are never removable by the tool, and the script never puts credentials on a command line or in the script itself (Remove DENY ACLs).
One apply per run directory
apply takes a lock file in its run directory, so two apply runs against that directory cannot race; a stale lock left by a dead process must be cleared with --force-unlock. The lock covers only apply. It does not coordinate who runs the generated scripts, or two operators using different run directories against the same MDS: plan for one operator per cluster during a migration window.
Related
- Delete the converted ACLs shows the deletion gates in use.
- Limitations and API stability lists what the tool does not do.
- The CLI overview maps each refusal to its exit code.