Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

This page is meant as a template for writing a KIP. To create a KIP choose Tools->Copy on this page and modify with your content and replace the heading with the next KIP number and a description of your issue. Replace anything in italics with your own description.

Status

Current state:  Draft Under discuss

Discussion thread: here [Change the link from the KIP proposal email archive to your own email thread]

...

Kafka's controller currently has no visibility into each broker's static configuration. When a broker registers with the controller via BrokerRegistrationRequest, it reports its supported feature versions, listeners, rack, and log directories, but not its configuration values (i.e., the settings defined in server.properties). This creates a fundamental gap that blocks one ticket and two categories of improvements:

This gap is not hypothetical — it has already produced observable technical debt in trunk. [KAFKA-20544] tracks  tracks the refactor of cordoned.log.dirs validation in ConfigurationControlManager, whose description explicitly states that the cleanup depends on making static configurations available in the controller. Today, because the controller cannot see each broker's log.dirs, validating cordoned.log.dirslog.dirs requires a resource-specific code path inside ConfigurationControlManager and a forwarded flag plumbed through the Controller interface — a workaround that the standard ConfigDef validator path should have made unnecessary. KAFKA-20544 is concrete evidence that the missing static configuration data is already shaping controller code in undesirable ways, and removing it is the prerequisite for that cleanup.

...

This KIP addresses the root cause shared by both problems: the controller lacks broker static configuration data. We propose that brokers include their static configurations in BrokerRegistrationRequest, and that the controller persists this information in RegisterBrokerRecord so it survives controller failovers. This KIP intentionally contains no validation logic — it provides only the infrastructure that KIP-1256 and KIP-1294 build upon.

Public Interfaces

ConfigDef

We propose a new configDef api to prevent security related configuration report to controller.

/**
* Whether this configuration must be excluded from
* {@code BrokerRegistrationRequest.StaticConfigs} (KIP-1326).
*
* <ul>
* <li>{@code DEFAULT} — defer to the broker-side filtering logic (currently
* validator-based: a config is reported if it has a {@link Validator} and
* is not {@code PASSWORD}).</li>
* <li>{@code NEVER} — explicit opt-out. The broker MUST NOT include this config
* under any circumstances, even if it gains a validator in the future.
* Intended for sensitive configs (PASSWORD, SSL/SASL secrets, reflective
* classes, free-form structured strings) as a defense-in-depth marker
* that survives future refactors of the inclusion logic.</li>
* </ul>
*
* There is intentionally no {@code ALWAYS} state: forcing a config without a
* validator into the registration request would defeat the purpose of the
* filter (the controller cannot validate values it has no validator for).
*/
public enum ControllerReportPolicy {
    DEFAULT,
    NEVER
}



/**
* Define a security-related configuration. The controller report policy is fixed at
* {@link ControllerReportPolicy#NEVER}, guaranteeing the broker will never include this
* config in {@code BrokerRegistrationRequest.StaticConfigs} (KIP-1326). Intended for
* SSL/SASL secrets, PASSWORD-type entries, JAAS configs, and other sensitive material
* that must never leave the broker.
*
* @param name The name of the config parameter
* @param type The type of the config
* @param defaultValue The default value to use if this config isn't present
* @param validator The validator to use in checking the correctness of the config
* @param importance The importance of this config
* @param documentation The documentation string for the config
* @return This ConfigDef so you can chain calls
*/
public ConfigDef defineSecurity(String name, Type type, Object defaultValue, Validator validator,
Importance importance, String documentation) {
return define(name, type, defaultValue, validator, importance, documentation,
ControllerReportPolicy.NEVER);
}

BrokerRegistrationRequest

...

We propose updating RegisterBrokerRecord to Version 5. This version introduces a new field StaticConfigs, which is a collection of BrokerStaticConfig objects. This allows the Controller to persist the broker's reported static settings directly within the metadata log.


BrokerRegerationRecordRegisterBrokerRecord.json

diff --git a/metadata/src/main/resources/common/metadata/RegisterBrokerRecord.json b/metadata/src/main/resources/common/metadata/RegisterBrokerRecord.json
index b7db680cbd..5570cbd96f 100644
--- a/metadata/src/main/resources/common/metadata/RegisterBrokerRecord.json
+++ b/metadata/src/main/resources/common/metadata/RegisterBrokerRecord.json
@@ -17,11 +17,12 @@
 // Version 2 adds IsMigratingZkBroker
 // Version 3 adds LogDirs
 // Version 4 adds CordonedLogDirs
+// Version 5 adds StaticConfigs for broker static config reporting.
 {
   "apiKey": 0,
   "type": "metadata",
   "name": "RegisterBrokerRecord",
-  "validVersions": "0-4",
+  "validVersions": "0-5",
   "flexibleVersions": "0+",
   "fields": [
     { "name": "BrokerId", "type": "int32", "versions": "0+", "entityType": "brokerId",
@@ -61,6 +62,16 @@
     { "name": "LogDirs", "type":  "[]uuid", "versions":  "3+", "taggedVersions": "3+", "tag": 0,
       "about": "Log directories configured in this broker which are available." },
     { "name": "CordonedLogDirs", "type":  "[]uuid", "versions":  "4+", "taggedVersions": "4+", "tag": "1",
-      "about": "Log directories that are cordoned." }
+      "about": "Log directories that are cordoned." },
+    { "name": "StaticConfigs", "type": "[]BrokerStaticConfig", "versions": "5+",
+      "taggedVersions": "5+", "tag": 2,
+      "about": "static configs from the broker's server.properties and default value.", "fields": [
+      { "name": "Name", "type": "string", "versions": "5+",
+        "about": "The config name." },
+      { "name": "Value", "type": "string", "versions": "5+", "nullableVersions": "5+",
+        "about": "The config value." },
+    ]}
   ]
 }

...

Proposed Changes

Broker side

A broker static config is included in BrokerRegistrationRequest.StaticConfigs iff (a) it has a Validator defined in ConfigDef, and (b) its ControllerReportPolicy is not NEVER.

The validator requirement keeps the reported set aligned with what the controller can actually enforce against future dynamic config changes — a config without a validator gives the controller nothing to validate, so reporting its value would only bloat the metadata log.

The NEVER policy is an explicit opt-out, applied via the defineSecurity(...) overload of ConfigDef. It is intended for sensitive material that must never be persisted in the metadata log. The opt-out is unconditional: the config is excluded even if it has (or later gains) a validator, so the guarantee survives future changes to the inclusion logicOnly configurations that have a validator defined in ConfigDef are included. This naturally excludes most security/SSL/SASL configs (which have no ConfigDef validator and rely on their own validation paths), as well as string/boolean configs that only have type checking. Sensitive configurations (ConfigDef.Type.PASSWORD) are also excluded.

Controller side

When receiving a BrokerRegistrationRequest v6 and the current MetadataVersion supports static configs, the controller copies the StaticConfigs field into the RegisterBrokerRecord.

...