Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

KIP-290 — Prefixed ACL resource patterns

Status: implemented — back to the KIP index.

What the KIP changes in Apache Kafka

Kafka 2.0 gave every ACL binding a pattern type: LITERAL (exact name, with * as a special literal wildcard) or PREFIXED (the binding covers every resource whose name starts with the stored prefix). Describe/Delete filters additionally gained a MATCH type that finds all bindings — literal, wildcard, or prefixed — affecting a given resource. The ACL wire APIs bumped to v1 to carry the new field.

How kaas implements it

  • Evaluation lives in matches_resource in crates/kaas-auth/src/acls.rs: literal matches on equality (with the * wildcard special-case), prefix uses starts_with, and a missing patternType defaults to literal. Deny short-circuits over allow, default is deny, and decisions sit in a 5-second cache that is wiped on every hot reload so a fresh deny rule bites immediately.
  • Authoring is CR-first: rules live on KafkaUser.spec.authorization.acls, whose CRD schema admits exactly literal and prefix (crates/kaas-operator-api/src/kafkauser.rs). The operator materialises them to /data/__cluster/acls.json (crates/kaas-operator-controllers/src/acls.rs); every broker hot-reloads the file.
  • The wire ACL trio (DescribeAcls 29 / CreateAcls 30 / DeleteAcls 31, all v0–v3, crates/kaas-broker/src/handlers/acls.rs) carries pattern types from v1 per the KIP; the enum mapping (LITERAL=3, PREFIXED=4) is in crates/kaas-codec/src/api/acl_types.rs. v0 requests are pinned to literal semantics on both create and filter, matching pre-KIP-290 behaviour. Writes go through the AclCRWriter onto the matching KafkaUser CR, so wire-created ACLs and CR-authored ACLs are the same rules.

Honest corners:

  • MATCH filters are approximated. match_pattern in crates/kaas-broker/src/acl_cr_writer.rs expands a MATCH filter to "literal or prefix bindings", but the resource-name axis still compares exactly — Apache's MATCH also finds prefixed bindings whose prefix merely covers the queried name, which kaas does not.
  • ACL host fields are stored but not enforced — only "any host" is evaluated today (noted in the CRD itself).
  • CreateAcls requires the principal's KafkaUser CR to exist; kaas has nowhere else to persist a rule.

How it's verified

  • crates/kaas-auth/src/acls.rs unit tests: prefix_pattern, deny_overrides_allow, reload_swaps_atomically, anonymous_default_denies.
  • crates/kaas-broker/src/handlers/acls.rs: wire_binding_translation_maps_enums (PREFIXED → prefix), v0_filter_defaults_to_literal_pattern.
  • scripts/kafka-acls.sh runs kafka-acls.sh CRUD end-to-end via a temporary KafkaUser CR (literal patterns only — it does not exercise prefixed bindings).

See also Listeners & auth for where the authorizer sits in the request path.