monedula-acl-rbac-converter docs menu
Remove DENY ACLs
Remove DENY ACLs with delete-deny-acls, whose script re-checks effective permissions per ACL at run time. Wildcard DENYs stay.
On this page
delete-acls never touches DENY ACLs. delete-deny-acls removes the ones you no longer need through a script that you run, which checks each DENY against MDS again at that moment and removes it only if that would not grant access.
Before you start
- A plan made with
--allow-rejected, which lists the DENY ACLs as rejected. See Plan and review role bindings. - A
verify.jsonfor the current plan, with every resultEFFECTIVE_OK, at its default place in the run directory, where the script reads it again.delete-deny-aclsrefuses while any result is missing or unknown. - MDS credentials as a token file, or a user name and a password file. A token cached by
auth loginis not enough: the script may run hours later, and it has to authenticate without you. - The bootstrap servers and a Kafka client properties file for a principal that may delete ACLs.
- A host with the run directory,
monedula-acl-rbacandkafka-aclson thePATH, to run the script. If your Kafka tool has another name or location, such askafka-acls.sh, setMONEDULA_KAFKA_ACLS_BINto it.
Steps
1. Check the DENY analysis
Read the DENY analysis section of report.txt. plan classifies every DENY ACL:
SAFE_TO_REMOVE: no Allow ACL in the input grants the same principal the same operation on that resource.WOULD_GRANT_ACCESS: an Allow ACL does, so removing the DENY would open access.UNKNOWN: the analysis cannot tell, as for every wildcard principal.
Only SAFE_TO_REMOVE DENY ACLs can be removed by this tool.
2. Generate the script
monedula-acl-rbac delete-deny-acls \
--plan runs/2026-05-21T10-00-00Z/plan.json \
--verify runs/2026-05-21T10-00-00Z/verify.json \
--mds-url https://mds.example.com \
--mds-token-file ~/.confluent/token \
--bootstrap-server kafka.example.com:9093 \
--command-config admin.properties \
--principal User:alice \
--confirm \
--i-understand-this-may-grant-access
--principal, or --principal-file, is required: there is no untargeted sweep. Both --confirm and --i-understand-this-may-grant-access are required too; --i-understand-this-is-destructive is not accepted on this command.
delete-deny-acls writes four files into the run directory:
delete-deny-acls.sh: the deletion script.deleted-deny-acls.json: the DENY ACLs that the script may remove.rollback-deny.sh: a script that recreates them.runtime.env: the Kafka and MDS connection settings, the credential references and a per-run token, with mode 0600. Secrets are never written into the script or onto command lines.
3. Read the script
The script contains no bare kafka-acls --remove calls. It checks that runtime.env exists with mode 0600, loads it, and then runs one line per DENY:
monedula-acl-rbac delete-deny-one --run-dir <absolute run directory> --acl-id <id>
delete-deny-one is an internal helper of this script, not a command you run yourself. For its ACL, it checks the plan and verify.json again, asks MDS whether the principal now holds any grant that overlaps the denied operation and resource, and removes the DENY only if none does. Because the check happens at run time, you can inspect, reorder or partly run the script by hand, even if access changed since you generated it.
4. Run the script
bash runs/2026-05-21T10-00-00Z/delete-deny-acls.sh
Like the delete-acls script, it refuses to run, with exit code 5, when plan.json changed or cannot be hashed. Each DENY gets one line in delete-deny.log:
OK: the live check found the DENY safe to remove, and it was removed.SKIPwithWOULD_GRANT_ACCESS: something now grants the denied access, for example a binding added after you planned, so the DENY stays. There is no override.SKIPwithEFFECTIVE_UNKNOWN: the live check failed, so the DENY stays.FAIL: the removal itself failed, and the script stops.
If MDS rejects the credentials, for example because the token expired, the script stops at that ACL instead of skipping the rest.
The script deletes runtime.env when it exits, so the per-run token does not outlive the run. To run it again, generate it again with delete-deny-acls.
Wildcard DENYs stay
DENY ACLs for a wildcard principal, such as User:*, a bare * or any <Type>:*, are never removable by this tool. They cover principals the analysis cannot enumerate, so plan classifies them UNKNOWN, delete-deny-acls will not include them and there is no override. If you are certain that one must go, remove it by hand with kafka-acls.
Check it worked
delete-deny.log has an OK line for each DENY that was removed and a SKIP line, with the reason, for each one that stayed. kafka-acls --list no longer shows the removed DENY ACLs. To restore them, run rollback-deny.sh against the same cluster.
Related
- Delete the converted ACLs handles the Allow ACLs.
- The delete-deny-acls command reference lists every flag and exit code.