You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jira@kafka.apache.org by "clolov (via GitHub)" <gi...@apache.org> on 2026/05/28 10:23:13 UTC
[PR] MINOR: A starting point for a formal security model [kafka]
clolov opened a new pull request, #22398:
URL: https://github.com/apache/kafka/pull/22398
This starting point has been inspired by other security models of Apache projects such as [Apache Tomcat](https://tomcat.apache.org/security-model.html) and [Apache Spark](https://spark.apache.org/docs/latest/security.html).
As a start it focuses on brokers first with the aim to expand it to clients, Connect, Streams etc. in subsequent PRs.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] MINOR: A starting point for a formal security model [kafka]
Posted by "mimaison (via GitHub)" <gi...@apache.org>.
mimaison commented on code in PR #22398:
URL: https://github.com/apache/kafka/pull/22398#discussion_r3396546188
##########
docs/security/security-model-connect.md:
##########
@@ -0,0 +1,93 @@
+---
+title: Kafka Connect Security Model
+description: Apache Kafka Connect Security Model
+weight: 9
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+This page extends the [Apache Kafka security model](security-model) to Kafka Connect. A worker authenticates to the Kafka cluster over a configured `SASL_SSL`/`SSL` listener exactly like any other client, so everything the core model says about authentication, authorization, and transport encryption to the brokers applies unchanged. What follows covers only what Connect adds on top — chiefly its own control plane, the REST API, and the fact that it runs user-supplied code.
+
+## Things You Need To Know
+
+- **Connect inherits the broker's client security model.** Authentication to the brokers, broker-side authorization, and transport encryption are exactly as described in the [core security model](security-model). This page only describes what Connect layers on top.
+- **The REST API is unauthenticated by default.** Out of the box, anyone who can reach the REST port can create, reconfigure, stop, or delete any connector. Because connectors and plugins run arbitrary code, unrestricted REST access is effectively unrestricted code execution on the worker.
+- **Connect plugins run arbitrary code.** Connectors, converters, transformations, predicates, and REST extensions loaded from `plugin.path` execute in the worker JVM with its privileges. Install only plugins you trust.
+- **The REST API is a shared control plane with no per-connector isolation.** There is no notion of connector ownership: any caller allowed onto the API can act on every connector and read its configuration.
+- **A worker authenticates to Kafka as a single principal.** By default all connectors on a worker share that principal's identity and ACLs; Connect does not give each connector a distinct Kafka identity. A connector can override the internal clients' configuration — including credentials — unless `connector.client.config.override.policy` restricts it (see Authorization below).
+- **In distributed mode, Connect stores its state in Kafka topics.** Connector configurations (including any inlined secrets), source offsets, and status live in the `config.storage.topic`, `offset.storage.topic`, and `status.storage.topic`; protect them with ACLs as you would any sensitive topic. In standalone mode, offsets are kept in a local file (`offset.storage.file.filename`) instead, so its protection is the host filesystem's responsibility.
Review Comment:
I see it's explained below
##########
docs/security/security-model-connect.md:
##########
@@ -0,0 +1,93 @@
+---
+title: Kafka Connect Security Model
+description: Apache Kafka Connect Security Model
+weight: 9
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+This page extends the [Apache Kafka security model](security-model) to Kafka Connect. A worker authenticates to the Kafka cluster over a configured `SASL_SSL`/`SSL` listener exactly like any other client, so everything the core model says about authentication, authorization, and transport encryption to the brokers applies unchanged. What follows covers only what Connect adds on top — chiefly its own control plane, the REST API, and the fact that it runs user-supplied code.
+
+## Things You Need To Know
+
+- **Connect inherits the broker's client security model.** Authentication to the brokers, broker-side authorization, and transport encryption are exactly as described in the [core security model](security-model). This page only describes what Connect layers on top.
+- **The REST API is unauthenticated by default.** Out of the box, anyone who can reach the REST port can create, reconfigure, stop, or delete any connector. Because connectors and plugins run arbitrary code, unrestricted REST access is effectively unrestricted code execution on the worker.
Review Comment:
I'm not sure it's `effectively unrestricted code execution on the worker`, as you can only use plugins installed on the worker, but it's still a lot of access
##########
docs/security/security-model-connect.md:
##########
@@ -0,0 +1,93 @@
+---
+title: Kafka Connect Security Model
+description: Apache Kafka Connect Security Model
+weight: 9
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+This page extends the [Apache Kafka security model](security-model) to Kafka Connect. A worker authenticates to the Kafka cluster over a configured `SASL_SSL`/`SSL` listener exactly like any other client, so everything the core model says about authentication, authorization, and transport encryption to the brokers applies unchanged. What follows covers only what Connect adds on top — chiefly its own control plane, the REST API, and the fact that it runs user-supplied code.
+
+## Things You Need To Know
+
+- **Connect inherits the broker's client security model.** Authentication to the brokers, broker-side authorization, and transport encryption are exactly as described in the [core security model](security-model). This page only describes what Connect layers on top.
+- **The REST API is unauthenticated by default.** Out of the box, anyone who can reach the REST port can create, reconfigure, stop, or delete any connector. Because connectors and plugins run arbitrary code, unrestricted REST access is effectively unrestricted code execution on the worker.
+- **Connect plugins run arbitrary code.** Connectors, converters, transformations, predicates, and REST extensions loaded from `plugin.path` execute in the worker JVM with its privileges. Install only plugins you trust.
+- **The REST API is a shared control plane with no per-connector isolation.** There is no notion of connector ownership: any caller allowed onto the API can act on every connector and read its configuration.
+- **A worker authenticates to Kafka as a single principal.** By default all connectors on a worker share that principal's identity and ACLs; Connect does not give each connector a distinct Kafka identity. A connector can override the internal clients' configuration — including credentials — unless `connector.client.config.override.policy` restricts it (see Authorization below).
+- **In distributed mode, Connect stores its state in Kafka topics.** Connector configurations (including any inlined secrets), source offsets, and status live in the `config.storage.topic`, `offset.storage.topic`, and `status.storage.topic`; protect them with ACLs as you would any sensitive topic. In standalone mode, offsets are kept in a local file (`offset.storage.file.filename`) instead, so its protection is the host filesystem's responsibility.
+
+## The REST API and the Network Boundary
+
+The REST API is configured with the `listeners` property (for example `http://host:port` or `https://host:port`); if unset it defaults to `http` on port 8083. In distributed mode the REST API is *also* the inter-worker transport — a request received by a follower is forwarded to the leader — so it is simultaneously a user-facing management interface and an internal control channel. `rest.advertised.host.name`, `rest.advertised.port`, and `rest.advertised.listener` control the URL other workers use to reach a node.
+
+Operators should:
+
+1. Never expose the REST API to untrusted networks or users; bind it to a management network or front it with a reverse proxy.
+2. Use `admin.listeners` to separate the admin endpoints from the regular listeners, or set it to empty to disable them where they are not needed.
+3. Prefer an `https` listener so that both user traffic and inter-worker forwarding are encrypted.
+
+## Authentication
+
+Connect enables no authentication on the REST API by default. There are two common ways to add it:
+
+- **Reverse proxy.** Terminate authentication (mTLS, OIDC, basic auth, etc.) in a proxy in front of the workers and allow only the proxy to reach the REST port.
+- **REST extension.** Register an authentication extension via `rest.extension.classes`. The built-in `BasicAuthSecurityRestExtension` performs JAAS-based HTTP basic authentication. Its reference `PropertyFileLoginModule` stores credentials in cleartext and is **not** intended for production — back it with a real `LoginModule` (LDAP, a database, etc.) instead.
Review Comment:
> Its reference `PropertyFileLoginModule` stores credentials in cleartext and is **not** intended for production — back it with a real `LoginModule` (LDAP, a database, etc.) instead.
That sentence seems weird.
##########
docs/security/security-model-connect.md:
##########
@@ -0,0 +1,93 @@
+---
+title: Kafka Connect Security Model
+description: Apache Kafka Connect Security Model
+weight: 9
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+This page extends the [Apache Kafka security model](security-model) to Kafka Connect. A worker authenticates to the Kafka cluster over a configured `SASL_SSL`/`SSL` listener exactly like any other client, so everything the core model says about authentication, authorization, and transport encryption to the brokers applies unchanged. What follows covers only what Connect adds on top — chiefly its own control plane, the REST API, and the fact that it runs user-supplied code.
+
+## Things You Need To Know
+
+- **Connect inherits the broker's client security model.** Authentication to the brokers, broker-side authorization, and transport encryption are exactly as described in the [core security model](security-model). This page only describes what Connect layers on top.
+- **The REST API is unauthenticated by default.** Out of the box, anyone who can reach the REST port can create, reconfigure, stop, or delete any connector. Because connectors and plugins run arbitrary code, unrestricted REST access is effectively unrestricted code execution on the worker.
+- **Connect plugins run arbitrary code.** Connectors, converters, transformations, predicates, and REST extensions loaded from `plugin.path` execute in the worker JVM with its privileges. Install only plugins you trust.
+- **The REST API is a shared control plane with no per-connector isolation.** There is no notion of connector ownership: any caller allowed onto the API can act on every connector and read its configuration.
+- **A worker authenticates to Kafka as a single principal.** By default all connectors on a worker share that principal's identity and ACLs; Connect does not give each connector a distinct Kafka identity. A connector can override the internal clients' configuration — including credentials — unless `connector.client.config.override.policy` restricts it (see Authorization below).
+- **In distributed mode, Connect stores its state in Kafka topics.** Connector configurations (including any inlined secrets), source offsets, and status live in the `config.storage.topic`, `offset.storage.topic`, and `status.storage.topic`; protect them with ACLs as you would any sensitive topic. In standalone mode, offsets are kept in a local file (`offset.storage.file.filename`) instead, so its protection is the host filesystem's responsibility.
Review Comment:
If you use configuration providers, only the template strings (`${alias:fields}`) is written to the config topic, not the resolved values. Still if you know a valid template string, it's often trivial to extract the secret if you have access to the REST API.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] MINOR: A starting point for a formal security model [kafka]
Posted by "mimaison (via GitHub)" <gi...@apache.org>.
mimaison commented on code in PR #22398:
URL: https://github.com/apache/kafka/pull/22398#discussion_r3388042404
##########
docs/security/security-model.md:
##########
@@ -0,0 +1,162 @@
+---
+title: Security Model
+description: Apache Kafka Security Model
+weight: 8
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+## Things You Need To Know
+
+- **Security is off by default.** A freshly-installed Apache Kafka cluster accepts unauthenticated `PLAINTEXT` connections on every listener and applies no authorization. This is appropriate only for closed test environments. Production deployments **must** explicitly configure authentication, authorization, and transport encryption before being exposed to any untrusted network.
+- **Apache Kafka assumes a trusted operator.** Anyone with shell access to a broker, controller, or the underlying disks can read every topic, forge any principal, and rewrite ACLs. The security model protects messages in transit and arbitrates client access — it does not defend brokers from their own administrators.
+- **Apache Kafka assumes a trusted broker fleet.** Brokers and KRaft controllers exchange records, replication state, and metadata over the inter-broker and controller listeners. Any host that can authenticate on those listeners is effectively part of the cluster's trust boundary.
+- **The data plane and the control plane have different exposure.** Producer/consumer traffic, the Admin API, and JMX each have distinct authentication and authorization stories. Operators must configure them independently — securing one does not secure the others.
+- **Apache Kafka does not encrypt data at rest.** Log segments, index files, and snapshots are written as plain bytes. At-rest confidentiality is the responsibility of the underlying filesystem, block device, or message-level encryption performed by producers.
+- **Reporting vulnerabilities.** Suspected security issues should be reported privately to `security@kafka.apache.org` per the [ASF security process](https://www.apache.org/security/). Do not file public JIRA tickets, GitHub issues, or mailing-list posts for unpatched vulnerabilities.
+
+## Listeners and the Network Boundary
+
+Apache Kafka brokers expose one or more **listeners**, each with an independent security configuration selected by `listener.security.protocol.map`. The four protocols are:
+
+| Protocol | Authentication | Encryption |
+|------------------|------------------------|------------|
+| `PLAINTEXT` | None | None |
+| `SSL` | Optional mTLS | TLS |
+| `SASL_PLAINTEXT` | SASL | None |
+| `SASL_SSL` | SASL (+ optional mTLS) | TLS |
+
+`inter.broker.listener.name` and `controller.listener.names` select which listeners carry replication and KRaft traffic respectively. A common pattern is to keep these on a dedicated internal listener (`SASL_SSL` or `SSL`) that is firewalled off from clients, so that a compromise of a client-facing listener cannot impersonate a broker.
+
+Operators should:
+
+1. Bind external listeners only to interfaces reachable by intended clients.
+2. Treat `advertised.listeners` as part of the security configuration — clients connect to whatever the broker advertises after the initial metadata fetch.
+3. Never expose the controller listener to client networks.
+
+## Authentication
+
+Apache Kafka supports two complementary authentication mechanisms; either may be used, and both can be combined on a `SASL_SSL` listener.
+
+### TLS Client Authentication (mTLS)
+
+When `ssl.client.auth` is `required` on a TLS listener, the client's X.509 certificate is verified against the broker's truststore. The authenticated principal is derived from the certificate's distinguished name via `ssl.principal.mapping.rules` (or a custom `KafkaPrincipalBuilder`).
+
+mTLS is the recommended mechanism for broker-to-broker and controller-to-broker traffic, because it requires no shared password material and rotates with the rest of the PKI.
+
+### SASL
+
+Apache Kafka ships with five SASL mechanisms, enabled per-listener via `sasl.enabled.mechanisms`:
+
+- **`GSSAPI`** — Kerberos. Recommended for environments that already operate a KDC; principals and credentials are managed externally.
+- **`SCRAM-SHA-256` / `SCRAM-SHA-512`** — Salted challenge/response with credentials stored in the cluster metadata. Credentials are managed with `kafka-configs.sh --alter --add-config 'SCRAM-SHA-512=...'`.
+- **`OAUTHBEARER`** — OAuth 2.0 bearer tokens, suitable for integration with an identity provider. The default unsecured implementation is for testing only; production deployments must configure a JWKS endpoint and validator.
+- **`PLAIN`** — Username/password sent in cleartext over the SASL channel. Acceptable only inside a `SASL_SSL` listener; never use it with `SASL_PLAINTEXT`.
+
+#### Delegation Tokens
+
+Once a client has authenticated via SASL or mTLS, it can request a short-lived **delegation token** that is then used as a `SCRAM-SHA-256` credential for subsequent connections. Delegation tokens are intended for distributed frameworks (Spark, Flink, Connect workers) that need to fan out to many tasks without distributing the original credential. Tokens inherit the requester's principal and ACLs, expire on a fixed schedule (`delegation.token.expiry.time.ms`), and can be invalidated by the owner.
+
+## Authorization
+
+Authentication establishes a `KafkaPrincipal`; authorization decides what that principal may do. Authorization is performed by the configured `authorizer.class.name`. Apache Kafka ships `org.apache.kafka.metadata.authorizer.StandardAuthorizer` for KRaft clusters.
+
+ACLs are tuples of `(principal, host, operation, resource pattern, permission)`. Resources are typed (`Topic`, `Group`, `Cluster`, `TransactionalId`, `DelegationToken`, `User`) and patterns may be `LITERAL` or `PREFIXED`.
+
+Defaults worth understanding:
+
+- If no authorizer is configured, **all authenticated principals have full access**. Configuring authentication without an authorizer provides identity but no authorization.
+- If an authorizer is configured but no ACLs match, access is **denied**. The exception is the principals listed in `super.users`, which bypass ACL checks entirely; treat that list as you would a root password.
+- `allow.everyone.if.no.acl.found=true` reverses the default-deny behaviour for resources that have no ACLs at all. It is a transitional aid for adding authorization to existing clusters and should not remain set in steady state.
+
+ACLs are managed with `kafka-acls.sh` or the AdminClient `createAcls`/`deleteAcls` APIs, which are themselves gated by ACLs on the `Cluster` resource.
+
+## Encryption in Transit
+
+TLS is configured per-listener via the standard `ssl.*` properties (`ssl.keystore.*`, `ssl.truststore.*`, `ssl.protocol`, `ssl.cipher.suites`, `ssl.enabled.protocols`). Recommendations:
+
+- Disable TLS versions below 1.2; prefer 1.3 where the JDK supports it.
+- Use distinct keystores for the inter-broker listener and any client-facing listener so that a leaked client-facing key cannot impersonate a broker.
+- Set `ssl.endpoint.identification.algorithm=https` on clients (the default since 2.0) so that the broker's certificate must match its hostname.
+- Rotate keystores using the dynamic broker configuration mechanism (`kafka-configs.sh --entity-type brokers --alter --add-config ...`) to avoid restarts.
+
+Kafka Connect, MirrorMaker 2, and Kafka Streams all consume the same `ssl.*` and `sasl.*` client configs — securing the broker is necessary but not sufficient.
+
+## Encryption at Rest
+
+Apache Kafka does not encrypt log segments, indexes, snapshots, or controller metadata on disk. Operators who require at-rest confidentiality have three options, in increasing order of cost:
+
+1. **Filesystem or block-device encryption** Transparent to Kafka; protects against disk theft and misdirected backups but not against anyone with broker login.
+2. **Message-level encryption.** Producers encrypt payloads (and optionally headers) before `send()`; consumers decrypt. Keys are managed by an external KMS. This is the only option that protects records from broker operators, but it precludes broker-side features that read payloads (e.g. Streams aggregations on the encrypted field).
+3. **Tiered storage** with a remote store that performs its own encryption.
+
+## Audit Logging
+
+Apache Kafka emits authorizer decisions to the `kafka.authorizer.logger` log4j logger. Setting this logger to `INFO` records every denied request; `DEBUG` records every allowed request as well. In regulated environments this log should be shipped to durable, append-only storage off-broker. There is no built-in tamper-evident audit trail.
+
+The request log (`kafka.request.logger`) provides finer detail on individual API calls and is useful for forensic investigation, but it is verbose and not enabled by default.
+
+## Secrets in Configuration
+
+Broker, client, and Connect properties files contain keystore passwords, SASL credentials, and similar secrets. Apache Kafka supports indirect references through `ConfigProvider` implementations (`FileConfigProvider`, `DirectoryConfigProvider`, or custom providers). Use them rather than embedding cleartext secrets in version-controlled configuration. For the file-based providers, set `allowed.paths` to the specific directories that hold those secrets so that a malicious or mistaken configuration cannot coerce the provider into reading arbitrary files elsewhere on the host. Sensitive dynamic broker configurations are encrypted at rest in the metadata log using `password.encoder.secret`; rotating that secret requires `password.encoder.old.secret` and a rolling restart.
+
+## Component-Specific Notes
+
+- **JMX.** Brokers expose operational metrics over JMX. JMX is an administrators/operators-only interface and must never be exposed to actual users. It is unauthenticated by default and should either be disabled, bound to localhost with an exporter alongside, or configured with `com.sun.management.jmxremote.authenticate=true` and TLS.
+
+The components built on top of the brokers and clients have their own security models, covered on separate pages:
+
+- [Kafka Connect](security-model-connect)
+- [Kafka Streams](security-model-streams)
+- [MirrorMaker 2](security-model-mirrormaker)
+
+## Development and Test Tooling
+
+Not everything shipped in the Apache Kafka source tree is part of the production attack surface. Some components exist only to develop, test, and release Kafka itself, and are explicitly out of scope for the security model — they are expected to run only in trusted development and CI environments, and issues in them are generally not treated as security vulnerabilities.
+
+- **Trogdor.** Trogdor is a test framework that injects faults and runs workloads by design, including arbitrary user-supplied commands. It is intended to run only in development environments; the project does not consider command execution through Trogdor a security issue.
+- **System tests and release tooling.** The `tests/` system-test harness and the scripts under `release/` are operator/developer tooling for building, testing, and publishing Kafka. They are not components of a running cluster.
+
+When assessing the attack surface of a deployed cluster, scope it to the brokers, KRaft controllers, the client and inter-broker/controller listeners, the Admin API, and JMX — not the development tooling above.
+
+## Classifying Reports
+
+To keep triage consistent, a reported issue is treated as exactly one of:
+
+- **A vulnerability** — it breaks one of the security properties above for an adversary that is in scope, such as an unauthenticated or unauthorized network client.
+- **A hardening suggestion** — no stated property is broken, but a safer default or an added guard would reduce the blast radius of misuse.
+- **Out of scope** — it requires capabilities the model already treats as trusted (operator-supplied configuration, keystores, ACL administration), an adversary the model does not cover (a trusted operator, peer broker, or controller), or an unsupported component (see Development and Test Tooling above).
+- **By design** — it concerns a property the model explicitly disclaims, such as at-rest confidentiality or isolation from a trusted operator.
+
+## Known Non-Findings
Review Comment:
Maybe it's obvious but only the currently supported releases and trunk are in scope.
We should also have a statement about our docker images. Apart from being CVE free on their release day, we don't rebuild release images, so eventually they all have CVEs so should probably be out of scope as well.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] MINOR: A starting point for a formal security model [kafka]
Posted by "mimaison (via GitHub)" <gi...@apache.org>.
mimaison commented on code in PR #22398:
URL: https://github.com/apache/kafka/pull/22398#discussion_r3332862661
##########
docs/security/security-model.md:
##########
@@ -0,0 +1,132 @@
+---
+title: Security Model
+description: Apache Kafka Security Model
+weight: 8
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+## Things You Need To Know
+
+- **Security is off by default.** A freshly-installed Apache Kafka cluster accepts unauthenticated `PLAINTEXT` connections on every listener and applies no authorization. This is appropriate only for closed test environments. Production deployments **must** explicitly configure authentication, authorization, and transport encryption before being exposed to any untrusted network.
+- **Apache Kafka assumes a trusted operator.** Anyone with shell access to a broker, controller, or the underlying disks can read every topic, forge any principal, and rewrite ACLs. The security model protects messages in transit and arbitrates client access — it does not defend brokers from their own administrators.
+- **Apache Kafka assumes a trusted broker fleet.** Brokers and KRaft controllers exchange records, replication state, and metadata over the inter-broker and controller listeners. Any host that can authenticate on those listeners is effectively part of the cluster's trust boundary.
+- **The data plane and the control plane have different exposure.** Producer/consumer traffic, the Admin API, the Kafka Connect REST API, and JMX each have distinct authentication and authorization stories. Operators must configure them independently — securing one does not secure the others.
+- **Apache Kafka does not encrypt data at rest.** Log segments, index files, and snapshots are written as plain bytes. At-rest confidentiality is the responsibility of the underlying filesystem, block device, or message-level encryption performed by producers.
+- **Reporting vulnerabilities.** Suspected security issues should be reported privately to `security@kafka.apache.org` per the [ASF security process](https://www.apache.org/security/). Do not file public JIRA tickets, GitHub issues, or mailing-list posts for unpatched vulnerabilities.
+
+## Listeners and the Network Boundary
+
+Apache Kafka brokers expose one or more **listeners**, each with an independent security configuration selected by `listener.security.protocol.map`. The four protocols are:
+
+| Protocol | Authentication | Encryption |
+|------------------|------------------------|------------|
+| `PLAINTEXT` | None | None |
+| `SSL` | Optional mTLS | TLS |
+| `SASL_PLAINTEXT` | SASL | None |
+| `SASL_SSL` | SASL (+ optional mTLS) | TLS |
+
+`inter.broker.listener.name` and `controller.listener.names` select which listeners carry replication and KRaft traffic respectively. A common pattern is to keep these on a dedicated internal listener (`SASL_SSL` or `SSL`) that is firewalled off from clients, so that a compromise of a client-facing listener cannot impersonate a broker.
+
+Operators should:
+
+1. Bind external listeners only to interfaces reachable by intended clients.
+2. Treat `advertised.listeners` as part of the security configuration — clients connect to whatever the broker advertises after the initial metadata fetch.
+3. Never expose the controller listener to client networks.
+
+## Authentication
+
+Apache Kafka supports two complementary authentication mechanisms; either may be used, and both can be combined on a `SASL_SSL` listener.
+
+### TLS Client Authentication (mTLS)
+
+When `ssl.client.auth` is `required` on a TLS listener, the client's X.509 certificate is verified against the broker's truststore. The authenticated principal is derived from the certificate's distinguished name via `ssl.principal.mapping.rules` (or a custom `KafkaPrincipalBuilder`).
+
+mTLS is the recommended mechanism for broker-to-broker and controller-to-broker traffic, because it requires no shared password material and rotates with the rest of the PKI.
+
+### SASL
+
+Apache Kafka ships with five SASL mechanisms, enabled per-listener via `sasl.enabled.mechanisms`:
+
+- **`GSSAPI`** — Kerberos. Recommended for environments that already operate a KDC; principals and credentials are managed externally.
+- **`SCRAM-SHA-256` / `SCRAM-SHA-512`** — Salted challenge/response with credentials stored in the cluster metadata. Credentials are managed with `kafka-configs.sh --alter --add-config 'SCRAM-SHA-512=...'`.
+- **`OAUTHBEARER`** — OAuth 2.0 bearer tokens, suitable for integration with an identity provider. The default unsecured implementation is for testing only; production deployments must configure a JWKS endpoint and validator.
+- **`PLAIN`** — Username/password sent in cleartext over the SASL channel. Acceptable only inside a `SASL_SSL` listener; never use it with `SASL_PLAINTEXT`.
+
+#### Delegation Tokens
+
+Once a client has authenticated via SASL or mTLS, it can request a short-lived **delegation token** that is then used as a `SCRAM-SHA-256` credential for subsequent connections. Delegation tokens are intended for distributed frameworks (Spark, Flink, Connect workers) that need to fan out to many tasks without distributing the original credential. Tokens inherit the requester's principal and ACLs, expire on a fixed schedule (`delegation.token.expiry.time.ms`), and can be invalidated by the owner.
+
+## Authorization
+
+Authentication establishes a `KafkaPrincipal`; authorization decides what that principal may do. Authorization is performed by the configured `authorizer.class.name`. Apache Kafka ships `org.apache.kafka.metadata.authorizer.StandardAuthorizer` for KRaft clusters.
+
+ACLs are tuples of `(principal, host, operation, resource pattern, permission)`. Resources are typed (`Topic`, `Group`, `Cluster`, `TransactionalId`, `DelegationToken`, `User`) and patterns may be `LITERAL` or `PREFIXED`.
+
+Defaults worth understanding:
+
+- If no authorizer is configured, **all authenticated principals have full access**. Configuring authentication without an authorizer provides identity but no authorization.
+- If an authorizer is configured but no ACLs match, access is **denied**. The exception is the principals listed in `super.users`, which bypass ACL checks entirely; treat that list as you would a root password.
+- `allow.everyone.if.no.acl.found=true` reverses the default-deny behaviour for resources that have no ACLs at all. It is a transitional aid for adding authorization to existing clusters and should not remain set in steady state.
+
+ACLs are managed with `kafka-acls.sh` or the AdminClient `createAcls`/`deleteAcls` APIs, which are themselves gated by ACLs on the `Cluster` resource.
+
+## Encryption in Transit
+
+TLS is configured per-listener via the standard `ssl.*` properties (`ssl.keystore.*`, `ssl.truststore.*`, `ssl.protocol`, `ssl.cipher.suites`, `ssl.enabled.protocols`). Recommendations:
+
+- Disable TLS versions below 1.2; prefer 1.3 where the JDK supports it.
+- Use distinct keystores for the inter-broker listener and any client-facing listener so that a leaked client-facing key cannot impersonate a broker.
+- Set `ssl.endpoint.identification.algorithm=https` on clients (the default since 2.0) so that the broker's certificate must match its hostname.
+- Rotate keystores using the dynamic broker configuration mechanism (`kafka-configs.sh --entity-type brokers --alter --add-config ...`) to avoid restarts.
+
+Kafka Connect, MirrorMaker 2, Kafka Streams, and the Schema Registry-style ecosystem tools all consume the same `ssl.*` and `sasl.*` client configs — securing the broker is necessary but not sufficient.
+
+## Encryption at Rest
+
+Apache Kafka does not encrypt log segments, indexes, snapshots, or controller metadata on disk. Operators who require at-rest confidentiality have three options, in increasing order of cost:
+
+1. **Filesystem or block-device encryption** Transparent to Kafka; protects against disk theft and misdirected backups but not against anyone with broker login.
+2. **Message-level encryption.** Producers encrypt payloads (and optionally headers) before `send()`; consumers decrypt. Keys are managed by an external KMS. This is the only option that protects records from broker operators, but it precludes broker-side features that read payloads (e.g. Streams aggregations on the encrypted field).
+3. **Tiered storage** with a remote store that performs its own encryption.
+
+## Audit Logging
+
+Apache Kafka emits authorizer decisions to the `kafka.authorizer.logger` log4j logger. Setting this logger to `INFO` records every denied request; `DEBUG` records every allowed request as well. In regulated environments this log should be shipped to durable, append-only storage off-broker. There is no built-in tamper-evident audit trail; integrate with the host's auditing pipeline.
+
+The request log (`kafka.request.logger`) provides finer detail on individual API calls and is useful for forensic investigation, but it is verbose and not enabled by default.
+
+## Secrets in Configuration
+
+Broker, client, and Connect properties files contain keystore passwords, SASL credentials, and similar secrets. Apache Kafka supports indirect references through `ConfigProvider` implementations (`FileConfigProvider`, `DirectoryConfigProvider`, or custom providers). Use them rather than embedding cleartext secrets in version-controlled configuration. Sensitive dynamic broker configurations are encrypted at rest in the metadata log using `password.encoder.secret`; rotating that secret requires `password.encoder.old.secret` and a rolling restart.
+
+## Component-Specific Notes
+
+- **Kafka Connect.** The REST API is unauthenticated by default; enable the built-in basic auth extension or front it with a reverse proxy. Connector configurations may contain credentials for external systems and should be stored via a `ConfigProvider`. Connect workers authenticate to the Kafka cluster as a single principal — partition that principal's ACLs by topic prefix per connector.
+- **Kafka Streams.** A Streams application authenticates as one principal that needs ACLs covering its source topics, internal repartition/changelog topics (typically `<application.id>-*`), and the consumer group `<application.id>`.
+- **MirrorMaker 2.** Replicates across security domains; configure `source.cluster.*` and `target.cluster.*` independently and never tunnel cleartext replication across an untrusted network.
+- **JMX.** Brokers expose operational metrics over JMX. JMX is unauthenticated by default and should either be disabled, bound to localhost with an exporter alongside, or configured with `com.sun.management.jmxremote.authenticate=true` and TLS.
Review Comment:
I mean in general, JMX is just too permissive to allow users to mess with it
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] MINOR: A starting point for a formal security model [kafka]
Posted by "clolov (via GitHub)" <gi...@apache.org>.
clolov commented on code in PR #22398:
URL: https://github.com/apache/kafka/pull/22398#discussion_r3324669783
##########
docs/security/security-model.md:
##########
@@ -0,0 +1,132 @@
+---
+title: Security Model
+description: Apache Kafka Security Model
+weight: 8
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+## Things You Need To Know
+
+- **Security is off by default.** A freshly-installed Apache Kafka cluster accepts unauthenticated `PLAINTEXT` connections on every listener and applies no authorization. This is appropriate only for closed test environments. Production deployments **must** explicitly configure authentication, authorization, and transport encryption before being exposed to any untrusted network.
+- **Apache Kafka assumes a trusted operator.** Anyone with shell access to a broker, controller, or the underlying disks can read every topic, forge any principal, and rewrite ACLs. The security model protects messages in transit and arbitrates client access — it does not defend brokers from their own administrators.
+- **Apache Kafka assumes a trusted broker fleet.** Brokers and KRaft controllers exchange records, replication state, and metadata over the inter-broker and controller listeners. Any host that can authenticate on those listeners is effectively part of the cluster's trust boundary.
+- **The data plane and the control plane have different exposure.** Producer/consumer traffic, the Admin API, the Kafka Connect REST API, and JMX each have distinct authentication and authorization stories. Operators must configure them independently — securing one does not secure the others.
+- **Apache Kafka does not encrypt data at rest.** Log segments, index files, and snapshots are written as plain bytes. At-rest confidentiality is the responsibility of the underlying filesystem, block device, or message-level encryption performed by producers.
+- **Reporting vulnerabilities.** Suspected security issues should be reported privately to `security@kafka.apache.org` per the [ASF security process](https://www.apache.org/security/). Do not file public JIRA tickets, GitHub issues, or mailing-list posts for unpatched vulnerabilities.
+
+## Listeners and the Network Boundary
+
+Apache Kafka brokers expose one or more **listeners**, each with an independent security configuration selected by `listener.security.protocol.map`. The four protocols are:
+
+| Protocol | Authentication | Encryption |
+|------------------|------------------------|------------|
+| `PLAINTEXT` | None | None |
+| `SSL` | Optional mTLS | TLS |
+| `SASL_PLAINTEXT` | SASL | None |
+| `SASL_SSL` | SASL (+ optional mTLS) | TLS |
+
+`inter.broker.listener.name` and `controller.listener.names` select which listeners carry replication and KRaft traffic respectively. A common pattern is to keep these on a dedicated internal listener (`SASL_SSL` or `SSL`) that is firewalled off from clients, so that a compromise of a client-facing listener cannot impersonate a broker.
+
+Operators should:
+
+1. Bind external listeners only to interfaces reachable by intended clients.
+2. Treat `advertised.listeners` as part of the security configuration — clients connect to whatever the broker advertises after the initial metadata fetch.
+3. Never expose the controller listener to client networks.
+
+## Authentication
+
+Apache Kafka supports two complementary authentication mechanisms; either may be used, and both can be combined on a `SASL_SSL` listener.
+
+### TLS Client Authentication (mTLS)
+
+When `ssl.client.auth` is `required` on a TLS listener, the client's X.509 certificate is verified against the broker's truststore. The authenticated principal is derived from the certificate's distinguished name via `ssl.principal.mapping.rules` (or a custom `KafkaPrincipalBuilder`).
+
+mTLS is the recommended mechanism for broker-to-broker and controller-to-broker traffic, because it requires no shared password material and rotates with the rest of the PKI.
+
+### SASL
+
+Apache Kafka ships with five SASL mechanisms, enabled per-listener via `sasl.enabled.mechanisms`:
+
+- **`GSSAPI`** — Kerberos. Recommended for environments that already operate a KDC; principals and credentials are managed externally.
+- **`SCRAM-SHA-256` / `SCRAM-SHA-512`** — Salted challenge/response with credentials stored in the cluster metadata. Credentials are managed with `kafka-configs.sh --alter --add-config 'SCRAM-SHA-512=...'`.
+- **`OAUTHBEARER`** — OAuth 2.0 bearer tokens, suitable for integration with an identity provider. The default unsecured implementation is for testing only; production deployments must configure a JWKS endpoint and validator.
+- **`PLAIN`** — Username/password sent in cleartext over the SASL channel. Acceptable only inside a `SASL_SSL` listener; never use it with `SASL_PLAINTEXT`.
+
+#### Delegation Tokens
+
+Once a client has authenticated via SASL or mTLS, it can request a short-lived **delegation token** that is then used as a `SCRAM-SHA-256` credential for subsequent connections. Delegation tokens are intended for distributed frameworks (Spark, Flink, Connect workers) that need to fan out to many tasks without distributing the original credential. Tokens inherit the requester's principal and ACLs, expire on a fixed schedule (`delegation.token.expiry.time.ms`), and can be invalidated by the owner.
+
+## Authorization
+
+Authentication establishes a `KafkaPrincipal`; authorization decides what that principal may do. Authorization is performed by the configured `authorizer.class.name`. Apache Kafka ships `org.apache.kafka.metadata.authorizer.StandardAuthorizer` for KRaft clusters.
+
+ACLs are tuples of `(principal, host, operation, resource pattern, permission)`. Resources are typed (`Topic`, `Group`, `Cluster`, `TransactionalId`, `DelegationToken`, `User`) and patterns may be `LITERAL` or `PREFIXED`.
+
+Defaults worth understanding:
+
+- If no authorizer is configured, **all authenticated principals have full access**. Configuring authentication without an authorizer provides identity but no authorization.
+- If an authorizer is configured but no ACLs match, access is **denied**. The exception is the principals listed in `super.users`, which bypass ACL checks entirely; treat that list as you would a root password.
+- `allow.everyone.if.no.acl.found=true` reverses the default-deny behaviour for resources that have no ACLs at all. It is a transitional aid for adding authorization to existing clusters and should not remain set in steady state.
+
+ACLs are managed with `kafka-acls.sh` or the AdminClient `createAcls`/`deleteAcls` APIs, which are themselves gated by ACLs on the `Cluster` resource.
+
+## Encryption in Transit
+
+TLS is configured per-listener via the standard `ssl.*` properties (`ssl.keystore.*`, `ssl.truststore.*`, `ssl.protocol`, `ssl.cipher.suites`, `ssl.enabled.protocols`). Recommendations:
+
+- Disable TLS versions below 1.2; prefer 1.3 where the JDK supports it.
+- Use distinct keystores for the inter-broker listener and any client-facing listener so that a leaked client-facing key cannot impersonate a broker.
+- Set `ssl.endpoint.identification.algorithm=https` on clients (the default since 2.0) so that the broker's certificate must match its hostname.
+- Rotate keystores using the dynamic broker configuration mechanism (`kafka-configs.sh --entity-type brokers --alter --add-config ...`) to avoid restarts.
+
+Kafka Connect, MirrorMaker 2, Kafka Streams, and the Schema Registry-style ecosystem tools all consume the same `ssl.*` and `sasl.*` client configs — securing the broker is necessary but not sufficient.
Review Comment:
Good catch, apologies, this is leftover from an earlier draft where I was also talking about how do tools interact with Kafka which I ended up scrapping. I will remove this!
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] MINOR: A starting point for a formal security model [kafka]
Posted by "mimaison (via GitHub)" <gi...@apache.org>.
mimaison commented on code in PR #22398:
URL: https://github.com/apache/kafka/pull/22398#discussion_r3317421668
##########
docs/security/security-model.md:
##########
@@ -0,0 +1,132 @@
+---
+title: Security Model
+description: Apache Kafka Security Model
+weight: 8
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+## Things You Need To Know
+
+- **Security is off by default.** A freshly-installed Apache Kafka cluster accepts unauthenticated `PLAINTEXT` connections on every listener and applies no authorization. This is appropriate only for closed test environments. Production deployments **must** explicitly configure authentication, authorization, and transport encryption before being exposed to any untrusted network.
+- **Apache Kafka assumes a trusted operator.** Anyone with shell access to a broker, controller, or the underlying disks can read every topic, forge any principal, and rewrite ACLs. The security model protects messages in transit and arbitrates client access — it does not defend brokers from their own administrators.
+- **Apache Kafka assumes a trusted broker fleet.** Brokers and KRaft controllers exchange records, replication state, and metadata over the inter-broker and controller listeners. Any host that can authenticate on those listeners is effectively part of the cluster's trust boundary.
+- **The data plane and the control plane have different exposure.** Producer/consumer traffic, the Admin API, the Kafka Connect REST API, and JMX each have distinct authentication and authorization stories. Operators must configure them independently — securing one does not secure the others.
+- **Apache Kafka does not encrypt data at rest.** Log segments, index files, and snapshots are written as plain bytes. At-rest confidentiality is the responsibility of the underlying filesystem, block device, or message-level encryption performed by producers.
+- **Reporting vulnerabilities.** Suspected security issues should be reported privately to `security@kafka.apache.org` per the [ASF security process](https://www.apache.org/security/). Do not file public JIRA tickets, GitHub issues, or mailing-list posts for unpatched vulnerabilities.
+
+## Listeners and the Network Boundary
+
+Apache Kafka brokers expose one or more **listeners**, each with an independent security configuration selected by `listener.security.protocol.map`. The four protocols are:
+
+| Protocol | Authentication | Encryption |
+|------------------|------------------------|------------|
+| `PLAINTEXT` | None | None |
+| `SSL` | Optional mTLS | TLS |
+| `SASL_PLAINTEXT` | SASL | None |
+| `SASL_SSL` | SASL (+ optional mTLS) | TLS |
+
+`inter.broker.listener.name` and `controller.listener.names` select which listeners carry replication and KRaft traffic respectively. A common pattern is to keep these on a dedicated internal listener (`SASL_SSL` or `SSL`) that is firewalled off from clients, so that a compromise of a client-facing listener cannot impersonate a broker.
+
+Operators should:
+
+1. Bind external listeners only to interfaces reachable by intended clients.
+2. Treat `advertised.listeners` as part of the security configuration — clients connect to whatever the broker advertises after the initial metadata fetch.
+3. Never expose the controller listener to client networks.
+
+## Authentication
+
+Apache Kafka supports two complementary authentication mechanisms; either may be used, and both can be combined on a `SASL_SSL` listener.
+
+### TLS Client Authentication (mTLS)
+
+When `ssl.client.auth` is `required` on a TLS listener, the client's X.509 certificate is verified against the broker's truststore. The authenticated principal is derived from the certificate's distinguished name via `ssl.principal.mapping.rules` (or a custom `KafkaPrincipalBuilder`).
+
+mTLS is the recommended mechanism for broker-to-broker and controller-to-broker traffic, because it requires no shared password material and rotates with the rest of the PKI.
+
+### SASL
+
+Apache Kafka ships with five SASL mechanisms, enabled per-listener via `sasl.enabled.mechanisms`:
+
+- **`GSSAPI`** — Kerberos. Recommended for environments that already operate a KDC; principals and credentials are managed externally.
+- **`SCRAM-SHA-256` / `SCRAM-SHA-512`** — Salted challenge/response with credentials stored in the cluster metadata. Credentials are managed with `kafka-configs.sh --alter --add-config 'SCRAM-SHA-512=...'`.
+- **`OAUTHBEARER`** — OAuth 2.0 bearer tokens, suitable for integration with an identity provider. The default unsecured implementation is for testing only; production deployments must configure a JWKS endpoint and validator.
+- **`PLAIN`** — Username/password sent in cleartext over the SASL channel. Acceptable only inside a `SASL_SSL` listener; never use it with `SASL_PLAINTEXT`.
+
+#### Delegation Tokens
+
+Once a client has authenticated via SASL or mTLS, it can request a short-lived **delegation token** that is then used as a `SCRAM-SHA-256` credential for subsequent connections. Delegation tokens are intended for distributed frameworks (Spark, Flink, Connect workers) that need to fan out to many tasks without distributing the original credential. Tokens inherit the requester's principal and ACLs, expire on a fixed schedule (`delegation.token.expiry.time.ms`), and can be invalidated by the owner.
+
+## Authorization
+
+Authentication establishes a `KafkaPrincipal`; authorization decides what that principal may do. Authorization is performed by the configured `authorizer.class.name`. Apache Kafka ships `org.apache.kafka.metadata.authorizer.StandardAuthorizer` for KRaft clusters.
+
+ACLs are tuples of `(principal, host, operation, resource pattern, permission)`. Resources are typed (`Topic`, `Group`, `Cluster`, `TransactionalId`, `DelegationToken`, `User`) and patterns may be `LITERAL` or `PREFIXED`.
+
+Defaults worth understanding:
+
+- If no authorizer is configured, **all authenticated principals have full access**. Configuring authentication without an authorizer provides identity but no authorization.
+- If an authorizer is configured but no ACLs match, access is **denied**. The exception is the principals listed in `super.users`, which bypass ACL checks entirely; treat that list as you would a root password.
+- `allow.everyone.if.no.acl.found=true` reverses the default-deny behaviour for resources that have no ACLs at all. It is a transitional aid for adding authorization to existing clusters and should not remain set in steady state.
+
+ACLs are managed with `kafka-acls.sh` or the AdminClient `createAcls`/`deleteAcls` APIs, which are themselves gated by ACLs on the `Cluster` resource.
+
+## Encryption in Transit
+
+TLS is configured per-listener via the standard `ssl.*` properties (`ssl.keystore.*`, `ssl.truststore.*`, `ssl.protocol`, `ssl.cipher.suites`, `ssl.enabled.protocols`). Recommendations:
+
+- Disable TLS versions below 1.2; prefer 1.3 where the JDK supports it.
+- Use distinct keystores for the inter-broker listener and any client-facing listener so that a leaked client-facing key cannot impersonate a broker.
+- Set `ssl.endpoint.identification.algorithm=https` on clients (the default since 2.0) so that the broker's certificate must match its hostname.
+- Rotate keystores using the dynamic broker configuration mechanism (`kafka-configs.sh --entity-type brokers --alter --add-config ...`) to avoid restarts.
+
+Kafka Connect, MirrorMaker 2, Kafka Streams, and the Schema Registry-style ecosystem tools all consume the same `ssl.*` and `sasl.*` client configs — securing the broker is necessary but not sufficient.
Review Comment:
What are you referring to with `the Schema Registry-style ecosystem tools`? That's not an Apache Kafka component, right?
##########
docs/security/security-model.md:
##########
@@ -0,0 +1,132 @@
+---
+title: Security Model
+description: Apache Kafka Security Model
+weight: 8
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+## Things You Need To Know
+
+- **Security is off by default.** A freshly-installed Apache Kafka cluster accepts unauthenticated `PLAINTEXT` connections on every listener and applies no authorization. This is appropriate only for closed test environments. Production deployments **must** explicitly configure authentication, authorization, and transport encryption before being exposed to any untrusted network.
+- **Apache Kafka assumes a trusted operator.** Anyone with shell access to a broker, controller, or the underlying disks can read every topic, forge any principal, and rewrite ACLs. The security model protects messages in transit and arbitrates client access — it does not defend brokers from their own administrators.
+- **Apache Kafka assumes a trusted broker fleet.** Brokers and KRaft controllers exchange records, replication state, and metadata over the inter-broker and controller listeners. Any host that can authenticate on those listeners is effectively part of the cluster's trust boundary.
+- **The data plane and the control plane have different exposure.** Producer/consumer traffic, the Admin API, the Kafka Connect REST API, and JMX each have distinct authentication and authorization stories. Operators must configure them independently — securing one does not secure the others.
+- **Apache Kafka does not encrypt data at rest.** Log segments, index files, and snapshots are written as plain bytes. At-rest confidentiality is the responsibility of the underlying filesystem, block device, or message-level encryption performed by producers.
+- **Reporting vulnerabilities.** Suspected security issues should be reported privately to `security@kafka.apache.org` per the [ASF security process](https://www.apache.org/security/). Do not file public JIRA tickets, GitHub issues, or mailing-list posts for unpatched vulnerabilities.
+
+## Listeners and the Network Boundary
+
+Apache Kafka brokers expose one or more **listeners**, each with an independent security configuration selected by `listener.security.protocol.map`. The four protocols are:
+
+| Protocol | Authentication | Encryption |
+|------------------|------------------------|------------|
+| `PLAINTEXT` | None | None |
+| `SSL` | Optional mTLS | TLS |
+| `SASL_PLAINTEXT` | SASL | None |
+| `SASL_SSL` | SASL (+ optional mTLS) | TLS |
+
+`inter.broker.listener.name` and `controller.listener.names` select which listeners carry replication and KRaft traffic respectively. A common pattern is to keep these on a dedicated internal listener (`SASL_SSL` or `SSL`) that is firewalled off from clients, so that a compromise of a client-facing listener cannot impersonate a broker.
+
+Operators should:
+
+1. Bind external listeners only to interfaces reachable by intended clients.
+2. Treat `advertised.listeners` as part of the security configuration — clients connect to whatever the broker advertises after the initial metadata fetch.
+3. Never expose the controller listener to client networks.
+
+## Authentication
+
+Apache Kafka supports two complementary authentication mechanisms; either may be used, and both can be combined on a `SASL_SSL` listener.
+
+### TLS Client Authentication (mTLS)
+
+When `ssl.client.auth` is `required` on a TLS listener, the client's X.509 certificate is verified against the broker's truststore. The authenticated principal is derived from the certificate's distinguished name via `ssl.principal.mapping.rules` (or a custom `KafkaPrincipalBuilder`).
+
+mTLS is the recommended mechanism for broker-to-broker and controller-to-broker traffic, because it requires no shared password material and rotates with the rest of the PKI.
+
+### SASL
+
+Apache Kafka ships with five SASL mechanisms, enabled per-listener via `sasl.enabled.mechanisms`:
+
+- **`GSSAPI`** — Kerberos. Recommended for environments that already operate a KDC; principals and credentials are managed externally.
+- **`SCRAM-SHA-256` / `SCRAM-SHA-512`** — Salted challenge/response with credentials stored in the cluster metadata. Credentials are managed with `kafka-configs.sh --alter --add-config 'SCRAM-SHA-512=...'`.
+- **`OAUTHBEARER`** — OAuth 2.0 bearer tokens, suitable for integration with an identity provider. The default unsecured implementation is for testing only; production deployments must configure a JWKS endpoint and validator.
+- **`PLAIN`** — Username/password sent in cleartext over the SASL channel. Acceptable only inside a `SASL_SSL` listener; never use it with `SASL_PLAINTEXT`.
+
+#### Delegation Tokens
+
+Once a client has authenticated via SASL or mTLS, it can request a short-lived **delegation token** that is then used as a `SCRAM-SHA-256` credential for subsequent connections. Delegation tokens are intended for distributed frameworks (Spark, Flink, Connect workers) that need to fan out to many tasks without distributing the original credential. Tokens inherit the requester's principal and ACLs, expire on a fixed schedule (`delegation.token.expiry.time.ms`), and can be invalidated by the owner.
+
+## Authorization
+
+Authentication establishes a `KafkaPrincipal`; authorization decides what that principal may do. Authorization is performed by the configured `authorizer.class.name`. Apache Kafka ships `org.apache.kafka.metadata.authorizer.StandardAuthorizer` for KRaft clusters.
+
+ACLs are tuples of `(principal, host, operation, resource pattern, permission)`. Resources are typed (`Topic`, `Group`, `Cluster`, `TransactionalId`, `DelegationToken`, `User`) and patterns may be `LITERAL` or `PREFIXED`.
+
+Defaults worth understanding:
+
+- If no authorizer is configured, **all authenticated principals have full access**. Configuring authentication without an authorizer provides identity but no authorization.
+- If an authorizer is configured but no ACLs match, access is **denied**. The exception is the principals listed in `super.users`, which bypass ACL checks entirely; treat that list as you would a root password.
+- `allow.everyone.if.no.acl.found=true` reverses the default-deny behaviour for resources that have no ACLs at all. It is a transitional aid for adding authorization to existing clusters and should not remain set in steady state.
+
+ACLs are managed with `kafka-acls.sh` or the AdminClient `createAcls`/`deleteAcls` APIs, which are themselves gated by ACLs on the `Cluster` resource.
+
+## Encryption in Transit
+
+TLS is configured per-listener via the standard `ssl.*` properties (`ssl.keystore.*`, `ssl.truststore.*`, `ssl.protocol`, `ssl.cipher.suites`, `ssl.enabled.protocols`). Recommendations:
+
+- Disable TLS versions below 1.2; prefer 1.3 where the JDK supports it.
+- Use distinct keystores for the inter-broker listener and any client-facing listener so that a leaked client-facing key cannot impersonate a broker.
+- Set `ssl.endpoint.identification.algorithm=https` on clients (the default since 2.0) so that the broker's certificate must match its hostname.
+- Rotate keystores using the dynamic broker configuration mechanism (`kafka-configs.sh --entity-type brokers --alter --add-config ...`) to avoid restarts.
+
+Kafka Connect, MirrorMaker 2, Kafka Streams, and the Schema Registry-style ecosystem tools all consume the same `ssl.*` and `sasl.*` client configs — securing the broker is necessary but not sufficient.
+
+## Encryption at Rest
+
+Apache Kafka does not encrypt log segments, indexes, snapshots, or controller metadata on disk. Operators who require at-rest confidentiality have three options, in increasing order of cost:
+
+1. **Filesystem or block-device encryption** Transparent to Kafka; protects against disk theft and misdirected backups but not against anyone with broker login.
+2. **Message-level encryption.** Producers encrypt payloads (and optionally headers) before `send()`; consumers decrypt. Keys are managed by an external KMS. This is the only option that protects records from broker operators, but it precludes broker-side features that read payloads (e.g. Streams aggregations on the encrypted field).
+3. **Tiered storage** with a remote store that performs its own encryption.
+
+## Audit Logging
+
+Apache Kafka emits authorizer decisions to the `kafka.authorizer.logger` log4j logger. Setting this logger to `INFO` records every denied request; `DEBUG` records every allowed request as well. In regulated environments this log should be shipped to durable, append-only storage off-broker. There is no built-in tamper-evident audit trail; integrate with the host's auditing pipeline.
+
+The request log (`kafka.request.logger`) provides finer detail on individual API calls and is useful for forensic investigation, but it is verbose and not enabled by default.
+
+## Secrets in Configuration
+
+Broker, client, and Connect properties files contain keystore passwords, SASL credentials, and similar secrets. Apache Kafka supports indirect references through `ConfigProvider` implementations (`FileConfigProvider`, `DirectoryConfigProvider`, or custom providers). Use them rather than embedding cleartext secrets in version-controlled configuration. Sensitive dynamic broker configurations are encrypted at rest in the metadata log using `password.encoder.secret`; rotating that secret requires `password.encoder.old.secret` and a rolling restart.
Review Comment:
Maybe we could also recommend setting the `allowed.paths` configuration to limit the folders these providers can access.
##########
docs/security/security-model.md:
##########
@@ -0,0 +1,132 @@
+---
+title: Security Model
+description: Apache Kafka Security Model
+weight: 8
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+## Things You Need To Know
+
+- **Security is off by default.** A freshly-installed Apache Kafka cluster accepts unauthenticated `PLAINTEXT` connections on every listener and applies no authorization. This is appropriate only for closed test environments. Production deployments **must** explicitly configure authentication, authorization, and transport encryption before being exposed to any untrusted network.
+- **Apache Kafka assumes a trusted operator.** Anyone with shell access to a broker, controller, or the underlying disks can read every topic, forge any principal, and rewrite ACLs. The security model protects messages in transit and arbitrates client access — it does not defend brokers from their own administrators.
+- **Apache Kafka assumes a trusted broker fleet.** Brokers and KRaft controllers exchange records, replication state, and metadata over the inter-broker and controller listeners. Any host that can authenticate on those listeners is effectively part of the cluster's trust boundary.
+- **The data plane and the control plane have different exposure.** Producer/consumer traffic, the Admin API, the Kafka Connect REST API, and JMX each have distinct authentication and authorization stories. Operators must configure them independently — securing one does not secure the others.
+- **Apache Kafka does not encrypt data at rest.** Log segments, index files, and snapshots are written as plain bytes. At-rest confidentiality is the responsibility of the underlying filesystem, block device, or message-level encryption performed by producers.
+- **Reporting vulnerabilities.** Suspected security issues should be reported privately to `security@kafka.apache.org` per the [ASF security process](https://www.apache.org/security/). Do not file public JIRA tickets, GitHub issues, or mailing-list posts for unpatched vulnerabilities.
+
+## Listeners and the Network Boundary
+
+Apache Kafka brokers expose one or more **listeners**, each with an independent security configuration selected by `listener.security.protocol.map`. The four protocols are:
+
+| Protocol | Authentication | Encryption |
+|------------------|------------------------|------------|
+| `PLAINTEXT` | None | None |
+| `SSL` | Optional mTLS | TLS |
+| `SASL_PLAINTEXT` | SASL | None |
+| `SASL_SSL` | SASL (+ optional mTLS) | TLS |
+
+`inter.broker.listener.name` and `controller.listener.names` select which listeners carry replication and KRaft traffic respectively. A common pattern is to keep these on a dedicated internal listener (`SASL_SSL` or `SSL`) that is firewalled off from clients, so that a compromise of a client-facing listener cannot impersonate a broker.
+
+Operators should:
+
+1. Bind external listeners only to interfaces reachable by intended clients.
+2. Treat `advertised.listeners` as part of the security configuration — clients connect to whatever the broker advertises after the initial metadata fetch.
+3. Never expose the controller listener to client networks.
+
+## Authentication
+
+Apache Kafka supports two complementary authentication mechanisms; either may be used, and both can be combined on a `SASL_SSL` listener.
+
+### TLS Client Authentication (mTLS)
+
+When `ssl.client.auth` is `required` on a TLS listener, the client's X.509 certificate is verified against the broker's truststore. The authenticated principal is derived from the certificate's distinguished name via `ssl.principal.mapping.rules` (or a custom `KafkaPrincipalBuilder`).
+
+mTLS is the recommended mechanism for broker-to-broker and controller-to-broker traffic, because it requires no shared password material and rotates with the rest of the PKI.
+
+### SASL
+
+Apache Kafka ships with five SASL mechanisms, enabled per-listener via `sasl.enabled.mechanisms`:
+
+- **`GSSAPI`** — Kerberos. Recommended for environments that already operate a KDC; principals and credentials are managed externally.
+- **`SCRAM-SHA-256` / `SCRAM-SHA-512`** — Salted challenge/response with credentials stored in the cluster metadata. Credentials are managed with `kafka-configs.sh --alter --add-config 'SCRAM-SHA-512=...'`.
+- **`OAUTHBEARER`** — OAuth 2.0 bearer tokens, suitable for integration with an identity provider. The default unsecured implementation is for testing only; production deployments must configure a JWKS endpoint and validator.
+- **`PLAIN`** — Username/password sent in cleartext over the SASL channel. Acceptable only inside a `SASL_SSL` listener; never use it with `SASL_PLAINTEXT`.
+
+#### Delegation Tokens
+
+Once a client has authenticated via SASL or mTLS, it can request a short-lived **delegation token** that is then used as a `SCRAM-SHA-256` credential for subsequent connections. Delegation tokens are intended for distributed frameworks (Spark, Flink, Connect workers) that need to fan out to many tasks without distributing the original credential. Tokens inherit the requester's principal and ACLs, expire on a fixed schedule (`delegation.token.expiry.time.ms`), and can be invalidated by the owner.
+
+## Authorization
+
+Authentication establishes a `KafkaPrincipal`; authorization decides what that principal may do. Authorization is performed by the configured `authorizer.class.name`. Apache Kafka ships `org.apache.kafka.metadata.authorizer.StandardAuthorizer` for KRaft clusters.
+
+ACLs are tuples of `(principal, host, operation, resource pattern, permission)`. Resources are typed (`Topic`, `Group`, `Cluster`, `TransactionalId`, `DelegationToken`, `User`) and patterns may be `LITERAL` or `PREFIXED`.
+
+Defaults worth understanding:
+
+- If no authorizer is configured, **all authenticated principals have full access**. Configuring authentication without an authorizer provides identity but no authorization.
+- If an authorizer is configured but no ACLs match, access is **denied**. The exception is the principals listed in `super.users`, which bypass ACL checks entirely; treat that list as you would a root password.
+- `allow.everyone.if.no.acl.found=true` reverses the default-deny behaviour for resources that have no ACLs at all. It is a transitional aid for adding authorization to existing clusters and should not remain set in steady state.
+
+ACLs are managed with `kafka-acls.sh` or the AdminClient `createAcls`/`deleteAcls` APIs, which are themselves gated by ACLs on the `Cluster` resource.
+
+## Encryption in Transit
+
+TLS is configured per-listener via the standard `ssl.*` properties (`ssl.keystore.*`, `ssl.truststore.*`, `ssl.protocol`, `ssl.cipher.suites`, `ssl.enabled.protocols`). Recommendations:
+
+- Disable TLS versions below 1.2; prefer 1.3 where the JDK supports it.
+- Use distinct keystores for the inter-broker listener and any client-facing listener so that a leaked client-facing key cannot impersonate a broker.
+- Set `ssl.endpoint.identification.algorithm=https` on clients (the default since 2.0) so that the broker's certificate must match its hostname.
+- Rotate keystores using the dynamic broker configuration mechanism (`kafka-configs.sh --entity-type brokers --alter --add-config ...`) to avoid restarts.
+
+Kafka Connect, MirrorMaker 2, Kafka Streams, and the Schema Registry-style ecosystem tools all consume the same `ssl.*` and `sasl.*` client configs — securing the broker is necessary but not sufficient.
+
+## Encryption at Rest
+
+Apache Kafka does not encrypt log segments, indexes, snapshots, or controller metadata on disk. Operators who require at-rest confidentiality have three options, in increasing order of cost:
+
+1. **Filesystem or block-device encryption** Transparent to Kafka; protects against disk theft and misdirected backups but not against anyone with broker login.
+2. **Message-level encryption.** Producers encrypt payloads (and optionally headers) before `send()`; consumers decrypt. Keys are managed by an external KMS. This is the only option that protects records from broker operators, but it precludes broker-side features that read payloads (e.g. Streams aggregations on the encrypted field).
+3. **Tiered storage** with a remote store that performs its own encryption.
+
+## Audit Logging
+
+Apache Kafka emits authorizer decisions to the `kafka.authorizer.logger` log4j logger. Setting this logger to `INFO` records every denied request; `DEBUG` records every allowed request as well. In regulated environments this log should be shipped to durable, append-only storage off-broker. There is no built-in tamper-evident audit trail; integrate with the host's auditing pipeline.
+
+The request log (`kafka.request.logger`) provides finer detail on individual API calls and is useful for forensic investigation, but it is verbose and not enabled by default.
+
+## Secrets in Configuration
+
+Broker, client, and Connect properties files contain keystore passwords, SASL credentials, and similar secrets. Apache Kafka supports indirect references through `ConfigProvider` implementations (`FileConfigProvider`, `DirectoryConfigProvider`, or custom providers). Use them rather than embedding cleartext secrets in version-controlled configuration. Sensitive dynamic broker configurations are encrypted at rest in the metadata log using `password.encoder.secret`; rotating that secret requires `password.encoder.old.secret` and a rolling restart.
+
+## Component-Specific Notes
+
+- **Kafka Connect.** The REST API is unauthenticated by default; enable the built-in basic auth extension or front it with a reverse proxy. Connector configurations may contain credentials for external systems and should be stored via a `ConfigProvider`. Connect workers authenticate to the Kafka cluster as a single principal — partition that principal's ACLs by topic prefix per connector.
Review Comment:
The biggest issues with Connect are:
- Shared REST API: Anyone with access can do anything including seeing other connectors' configurations but also stopping or deleting them
- Shared ConfigProviders: If you can guess the config provider alias, anyone with access to the REST API can fully retrieve its configuration
- Client configuration overrides are enabled by default: `connector.client.config.override.policy` defaults to `All`. We've voted to change that to Allowlist in 5.0 but till then, by default, users with access to the REST API can mess with Connect's internal clients can potentially retrieve their configurations (including sensitive ones)
Bottom line is
1. You can't grant access to the Connect REST API to users that are not trusted as administrators
2. If multiple users need Connect, you should deploy multiple Connect clusters to isolate them
Security wise Connect is in a pretty sorry state.
##########
docs/security/security-model.md:
##########
@@ -0,0 +1,132 @@
+---
+title: Security Model
+description: Apache Kafka Security Model
+weight: 8
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+## Things You Need To Know
+
+- **Security is off by default.** A freshly-installed Apache Kafka cluster accepts unauthenticated `PLAINTEXT` connections on every listener and applies no authorization. This is appropriate only for closed test environments. Production deployments **must** explicitly configure authentication, authorization, and transport encryption before being exposed to any untrusted network.
+- **Apache Kafka assumes a trusted operator.** Anyone with shell access to a broker, controller, or the underlying disks can read every topic, forge any principal, and rewrite ACLs. The security model protects messages in transit and arbitrates client access — it does not defend brokers from their own administrators.
+- **Apache Kafka assumes a trusted broker fleet.** Brokers and KRaft controllers exchange records, replication state, and metadata over the inter-broker and controller listeners. Any host that can authenticate on those listeners is effectively part of the cluster's trust boundary.
+- **The data plane and the control plane have different exposure.** Producer/consumer traffic, the Admin API, the Kafka Connect REST API, and JMX each have distinct authentication and authorization stories. Operators must configure them independently — securing one does not secure the others.
+- **Apache Kafka does not encrypt data at rest.** Log segments, index files, and snapshots are written as plain bytes. At-rest confidentiality is the responsibility of the underlying filesystem, block device, or message-level encryption performed by producers.
+- **Reporting vulnerabilities.** Suspected security issues should be reported privately to `security@kafka.apache.org` per the [ASF security process](https://www.apache.org/security/). Do not file public JIRA tickets, GitHub issues, or mailing-list posts for unpatched vulnerabilities.
+
+## Listeners and the Network Boundary
+
+Apache Kafka brokers expose one or more **listeners**, each with an independent security configuration selected by `listener.security.protocol.map`. The four protocols are:
+
+| Protocol | Authentication | Encryption |
+|------------------|------------------------|------------|
+| `PLAINTEXT` | None | None |
+| `SSL` | Optional mTLS | TLS |
+| `SASL_PLAINTEXT` | SASL | None |
+| `SASL_SSL` | SASL (+ optional mTLS) | TLS |
+
+`inter.broker.listener.name` and `controller.listener.names` select which listeners carry replication and KRaft traffic respectively. A common pattern is to keep these on a dedicated internal listener (`SASL_SSL` or `SSL`) that is firewalled off from clients, so that a compromise of a client-facing listener cannot impersonate a broker.
+
+Operators should:
+
+1. Bind external listeners only to interfaces reachable by intended clients.
+2. Treat `advertised.listeners` as part of the security configuration — clients connect to whatever the broker advertises after the initial metadata fetch.
+3. Never expose the controller listener to client networks.
+
+## Authentication
+
+Apache Kafka supports two complementary authentication mechanisms; either may be used, and both can be combined on a `SASL_SSL` listener.
+
+### TLS Client Authentication (mTLS)
+
+When `ssl.client.auth` is `required` on a TLS listener, the client's X.509 certificate is verified against the broker's truststore. The authenticated principal is derived from the certificate's distinguished name via `ssl.principal.mapping.rules` (or a custom `KafkaPrincipalBuilder`).
+
+mTLS is the recommended mechanism for broker-to-broker and controller-to-broker traffic, because it requires no shared password material and rotates with the rest of the PKI.
+
+### SASL
+
+Apache Kafka ships with five SASL mechanisms, enabled per-listener via `sasl.enabled.mechanisms`:
+
+- **`GSSAPI`** — Kerberos. Recommended for environments that already operate a KDC; principals and credentials are managed externally.
+- **`SCRAM-SHA-256` / `SCRAM-SHA-512`** — Salted challenge/response with credentials stored in the cluster metadata. Credentials are managed with `kafka-configs.sh --alter --add-config 'SCRAM-SHA-512=...'`.
+- **`OAUTHBEARER`** — OAuth 2.0 bearer tokens, suitable for integration with an identity provider. The default unsecured implementation is for testing only; production deployments must configure a JWKS endpoint and validator.
+- **`PLAIN`** — Username/password sent in cleartext over the SASL channel. Acceptable only inside a `SASL_SSL` listener; never use it with `SASL_PLAINTEXT`.
+
+#### Delegation Tokens
+
+Once a client has authenticated via SASL or mTLS, it can request a short-lived **delegation token** that is then used as a `SCRAM-SHA-256` credential for subsequent connections. Delegation tokens are intended for distributed frameworks (Spark, Flink, Connect workers) that need to fan out to many tasks without distributing the original credential. Tokens inherit the requester's principal and ACLs, expire on a fixed schedule (`delegation.token.expiry.time.ms`), and can be invalidated by the owner.
+
+## Authorization
+
+Authentication establishes a `KafkaPrincipal`; authorization decides what that principal may do. Authorization is performed by the configured `authorizer.class.name`. Apache Kafka ships `org.apache.kafka.metadata.authorizer.StandardAuthorizer` for KRaft clusters.
+
+ACLs are tuples of `(principal, host, operation, resource pattern, permission)`. Resources are typed (`Topic`, `Group`, `Cluster`, `TransactionalId`, `DelegationToken`, `User`) and patterns may be `LITERAL` or `PREFIXED`.
+
+Defaults worth understanding:
+
+- If no authorizer is configured, **all authenticated principals have full access**. Configuring authentication without an authorizer provides identity but no authorization.
+- If an authorizer is configured but no ACLs match, access is **denied**. The exception is the principals listed in `super.users`, which bypass ACL checks entirely; treat that list as you would a root password.
+- `allow.everyone.if.no.acl.found=true` reverses the default-deny behaviour for resources that have no ACLs at all. It is a transitional aid for adding authorization to existing clusters and should not remain set in steady state.
+
+ACLs are managed with `kafka-acls.sh` or the AdminClient `createAcls`/`deleteAcls` APIs, which are themselves gated by ACLs on the `Cluster` resource.
+
+## Encryption in Transit
+
+TLS is configured per-listener via the standard `ssl.*` properties (`ssl.keystore.*`, `ssl.truststore.*`, `ssl.protocol`, `ssl.cipher.suites`, `ssl.enabled.protocols`). Recommendations:
+
+- Disable TLS versions below 1.2; prefer 1.3 where the JDK supports it.
+- Use distinct keystores for the inter-broker listener and any client-facing listener so that a leaked client-facing key cannot impersonate a broker.
+- Set `ssl.endpoint.identification.algorithm=https` on clients (the default since 2.0) so that the broker's certificate must match its hostname.
+- Rotate keystores using the dynamic broker configuration mechanism (`kafka-configs.sh --entity-type brokers --alter --add-config ...`) to avoid restarts.
+
+Kafka Connect, MirrorMaker 2, Kafka Streams, and the Schema Registry-style ecosystem tools all consume the same `ssl.*` and `sasl.*` client configs — securing the broker is necessary but not sufficient.
+
+## Encryption at Rest
+
+Apache Kafka does not encrypt log segments, indexes, snapshots, or controller metadata on disk. Operators who require at-rest confidentiality have three options, in increasing order of cost:
+
+1. **Filesystem or block-device encryption** Transparent to Kafka; protects against disk theft and misdirected backups but not against anyone with broker login.
+2. **Message-level encryption.** Producers encrypt payloads (and optionally headers) before `send()`; consumers decrypt. Keys are managed by an external KMS. This is the only option that protects records from broker operators, but it precludes broker-side features that read payloads (e.g. Streams aggregations on the encrypted field).
+3. **Tiered storage** with a remote store that performs its own encryption.
+
+## Audit Logging
+
+Apache Kafka emits authorizer decisions to the `kafka.authorizer.logger` log4j logger. Setting this logger to `INFO` records every denied request; `DEBUG` records every allowed request as well. In regulated environments this log should be shipped to durable, append-only storage off-broker. There is no built-in tamper-evident audit trail; integrate with the host's auditing pipeline.
+
+The request log (`kafka.request.logger`) provides finer detail on individual API calls and is useful for forensic investigation, but it is verbose and not enabled by default.
+
+## Secrets in Configuration
+
+Broker, client, and Connect properties files contain keystore passwords, SASL credentials, and similar secrets. Apache Kafka supports indirect references through `ConfigProvider` implementations (`FileConfigProvider`, `DirectoryConfigProvider`, or custom providers). Use them rather than embedding cleartext secrets in version-controlled configuration. Sensitive dynamic broker configurations are encrypted at rest in the metadata log using `password.encoder.secret`; rotating that secret requires `password.encoder.old.secret` and a rolling restart.
+
+## Component-Specific Notes
+
+- **Kafka Connect.** The REST API is unauthenticated by default; enable the built-in basic auth extension or front it with a reverse proxy. Connector configurations may contain credentials for external systems and should be stored via a `ConfigProvider`. Connect workers authenticate to the Kafka cluster as a single principal — partition that principal's ACLs by topic prefix per connector.
+- **Kafka Streams.** A Streams application authenticates as one principal that needs ACLs covering its source topics, internal repartition/changelog topics (typically `<application.id>-*`), and the consumer group `<application.id>`.
+- **MirrorMaker 2.** Replicates across security domains; configure `source.cluster.*` and `target.cluster.*` independently and never tunnel cleartext replication across an untrusted network.
+- **JMX.** Brokers expose operational metrics over JMX. JMX is unauthenticated by default and should either be disabled, bound to localhost with an exporter alongside, or configured with `com.sun.management.jmxremote.authenticate=true` and TLS.
Review Comment:
And never be exposed to actual users. JMX is for administrators/operators only.
##########
docs/security/security-model.md:
##########
@@ -0,0 +1,132 @@
+---
+title: Security Model
+description: Apache Kafka Security Model
+weight: 8
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+## Things You Need To Know
+
+- **Security is off by default.** A freshly-installed Apache Kafka cluster accepts unauthenticated `PLAINTEXT` connections on every listener and applies no authorization. This is appropriate only for closed test environments. Production deployments **must** explicitly configure authentication, authorization, and transport encryption before being exposed to any untrusted network.
+- **Apache Kafka assumes a trusted operator.** Anyone with shell access to a broker, controller, or the underlying disks can read every topic, forge any principal, and rewrite ACLs. The security model protects messages in transit and arbitrates client access — it does not defend brokers from their own administrators.
+- **Apache Kafka assumes a trusted broker fleet.** Brokers and KRaft controllers exchange records, replication state, and metadata over the inter-broker and controller listeners. Any host that can authenticate on those listeners is effectively part of the cluster's trust boundary.
+- **The data plane and the control plane have different exposure.** Producer/consumer traffic, the Admin API, the Kafka Connect REST API, and JMX each have distinct authentication and authorization stories. Operators must configure them independently — securing one does not secure the others.
+- **Apache Kafka does not encrypt data at rest.** Log segments, index files, and snapshots are written as plain bytes. At-rest confidentiality is the responsibility of the underlying filesystem, block device, or message-level encryption performed by producers.
+- **Reporting vulnerabilities.** Suspected security issues should be reported privately to `security@kafka.apache.org` per the [ASF security process](https://www.apache.org/security/). Do not file public JIRA tickets, GitHub issues, or mailing-list posts for unpatched vulnerabilities.
+
+## Listeners and the Network Boundary
+
+Apache Kafka brokers expose one or more **listeners**, each with an independent security configuration selected by `listener.security.protocol.map`. The four protocols are:
+
+| Protocol | Authentication | Encryption |
+|------------------|------------------------|------------|
+| `PLAINTEXT` | None | None |
+| `SSL` | Optional mTLS | TLS |
+| `SASL_PLAINTEXT` | SASL | None |
+| `SASL_SSL` | SASL (+ optional mTLS) | TLS |
+
+`inter.broker.listener.name` and `controller.listener.names` select which listeners carry replication and KRaft traffic respectively. A common pattern is to keep these on a dedicated internal listener (`SASL_SSL` or `SSL`) that is firewalled off from clients, so that a compromise of a client-facing listener cannot impersonate a broker.
+
+Operators should:
+
+1. Bind external listeners only to interfaces reachable by intended clients.
+2. Treat `advertised.listeners` as part of the security configuration — clients connect to whatever the broker advertises after the initial metadata fetch.
+3. Never expose the controller listener to client networks.
+
+## Authentication
+
+Apache Kafka supports two complementary authentication mechanisms; either may be used, and both can be combined on a `SASL_SSL` listener.
+
+### TLS Client Authentication (mTLS)
+
+When `ssl.client.auth` is `required` on a TLS listener, the client's X.509 certificate is verified against the broker's truststore. The authenticated principal is derived from the certificate's distinguished name via `ssl.principal.mapping.rules` (or a custom `KafkaPrincipalBuilder`).
+
+mTLS is the recommended mechanism for broker-to-broker and controller-to-broker traffic, because it requires no shared password material and rotates with the rest of the PKI.
+
+### SASL
+
+Apache Kafka ships with five SASL mechanisms, enabled per-listener via `sasl.enabled.mechanisms`:
+
+- **`GSSAPI`** — Kerberos. Recommended for environments that already operate a KDC; principals and credentials are managed externally.
+- **`SCRAM-SHA-256` / `SCRAM-SHA-512`** — Salted challenge/response with credentials stored in the cluster metadata. Credentials are managed with `kafka-configs.sh --alter --add-config 'SCRAM-SHA-512=...'`.
+- **`OAUTHBEARER`** — OAuth 2.0 bearer tokens, suitable for integration with an identity provider. The default unsecured implementation is for testing only; production deployments must configure a JWKS endpoint and validator.
+- **`PLAIN`** — Username/password sent in cleartext over the SASL channel. Acceptable only inside a `SASL_SSL` listener; never use it with `SASL_PLAINTEXT`.
+
+#### Delegation Tokens
+
+Once a client has authenticated via SASL or mTLS, it can request a short-lived **delegation token** that is then used as a `SCRAM-SHA-256` credential for subsequent connections. Delegation tokens are intended for distributed frameworks (Spark, Flink, Connect workers) that need to fan out to many tasks without distributing the original credential. Tokens inherit the requester's principal and ACLs, expire on a fixed schedule (`delegation.token.expiry.time.ms`), and can be invalidated by the owner.
+
+## Authorization
+
+Authentication establishes a `KafkaPrincipal`; authorization decides what that principal may do. Authorization is performed by the configured `authorizer.class.name`. Apache Kafka ships `org.apache.kafka.metadata.authorizer.StandardAuthorizer` for KRaft clusters.
+
+ACLs are tuples of `(principal, host, operation, resource pattern, permission)`. Resources are typed (`Topic`, `Group`, `Cluster`, `TransactionalId`, `DelegationToken`, `User`) and patterns may be `LITERAL` or `PREFIXED`.
+
+Defaults worth understanding:
+
+- If no authorizer is configured, **all authenticated principals have full access**. Configuring authentication without an authorizer provides identity but no authorization.
+- If an authorizer is configured but no ACLs match, access is **denied**. The exception is the principals listed in `super.users`, which bypass ACL checks entirely; treat that list as you would a root password.
+- `allow.everyone.if.no.acl.found=true` reverses the default-deny behaviour for resources that have no ACLs at all. It is a transitional aid for adding authorization to existing clusters and should not remain set in steady state.
+
+ACLs are managed with `kafka-acls.sh` or the AdminClient `createAcls`/`deleteAcls` APIs, which are themselves gated by ACLs on the `Cluster` resource.
+
+## Encryption in Transit
+
+TLS is configured per-listener via the standard `ssl.*` properties (`ssl.keystore.*`, `ssl.truststore.*`, `ssl.protocol`, `ssl.cipher.suites`, `ssl.enabled.protocols`). Recommendations:
+
+- Disable TLS versions below 1.2; prefer 1.3 where the JDK supports it.
+- Use distinct keystores for the inter-broker listener and any client-facing listener so that a leaked client-facing key cannot impersonate a broker.
+- Set `ssl.endpoint.identification.algorithm=https` on clients (the default since 2.0) so that the broker's certificate must match its hostname.
+- Rotate keystores using the dynamic broker configuration mechanism (`kafka-configs.sh --entity-type brokers --alter --add-config ...`) to avoid restarts.
+
+Kafka Connect, MirrorMaker 2, Kafka Streams, and the Schema Registry-style ecosystem tools all consume the same `ssl.*` and `sasl.*` client configs — securing the broker is necessary but not sufficient.
+
+## Encryption at Rest
+
+Apache Kafka does not encrypt log segments, indexes, snapshots, or controller metadata on disk. Operators who require at-rest confidentiality have three options, in increasing order of cost:
+
+1. **Filesystem or block-device encryption** Transparent to Kafka; protects against disk theft and misdirected backups but not against anyone with broker login.
+2. **Message-level encryption.** Producers encrypt payloads (and optionally headers) before `send()`; consumers decrypt. Keys are managed by an external KMS. This is the only option that protects records from broker operators, but it precludes broker-side features that read payloads (e.g. Streams aggregations on the encrypted field).
+3. **Tiered storage** with a remote store that performs its own encryption.
+
+## Audit Logging
+
+Apache Kafka emits authorizer decisions to the `kafka.authorizer.logger` log4j logger. Setting this logger to `INFO` records every denied request; `DEBUG` records every allowed request as well. In regulated environments this log should be shipped to durable, append-only storage off-broker. There is no built-in tamper-evident audit trail; integrate with the host's auditing pipeline.
+
+The request log (`kafka.request.logger`) provides finer detail on individual API calls and is useful for forensic investigation, but it is verbose and not enabled by default.
+
+## Secrets in Configuration
+
+Broker, client, and Connect properties files contain keystore passwords, SASL credentials, and similar secrets. Apache Kafka supports indirect references through `ConfigProvider` implementations (`FileConfigProvider`, `DirectoryConfigProvider`, or custom providers). Use them rather than embedding cleartext secrets in version-controlled configuration. Sensitive dynamic broker configurations are encrypted at rest in the metadata log using `password.encoder.secret`; rotating that secret requires `password.encoder.old.secret` and a rolling restart.
+
+## Component-Specific Notes
+
+- **Kafka Connect.** The REST API is unauthenticated by default; enable the built-in basic auth extension or front it with a reverse proxy. Connector configurations may contain credentials for external systems and should be stored via a `ConfigProvider`. Connect workers authenticate to the Kafka cluster as a single principal — partition that principal's ACLs by topic prefix per connector.
+- **Kafka Streams.** A Streams application authenticates as one principal that needs ACLs covering its source topics, internal repartition/changelog topics (typically `<application.id>-*`), and the consumer group `<application.id>`.
+- **MirrorMaker 2.** Replicates across security domains; configure `source.cluster.*` and `target.cluster.*` independently and never tunnel cleartext replication across an untrusted network.
+- **JMX.** Brokers expose operational metrics over JMX. JMX is unauthenticated by default and should either be disabled, bound to localhost with an exporter alongside, or configured with `com.sun.management.jmxremote.authenticate=true` and TLS.
+
Review Comment:
Should we have a section for development tools? For example mark Trogdor as a development tool and potentially illegible to security issues.
Could the same could be said about the release tools, system tests? The idea is to define what's considered the attack surface for Apache Kafka.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] MINOR: A starting point for a formal security model [kafka]
Posted by "clolov (via GitHub)" <gi...@apache.org>.
clolov commented on code in PR #22398:
URL: https://github.com/apache/kafka/pull/22398#discussion_r3396243285
##########
docs/security/security-model-mirrormaker.md:
##########
@@ -0,0 +1,35 @@
+---
+title: MirrorMaker 2 Security Model
+description: Apache Kafka MirrorMaker 2 Security Model
+weight: 11
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+This page extends the [Apache Kafka security model](security-model) to MirrorMaker 2. MirrorMaker 2 is built on Kafka Connect, so the [Connect security model](security-model-connect) applies in full; what follows is specific to replicating across clusters.
Review Comment:
I have added a couple of notices for MirrorMaker in the latest commits. This being said I am also okay with folding it within Connect. To be honest, I do not interact with MirrorMaker on daily basis, so my knowledge in the area is sparse :(
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] MINOR: A starting point for a formal security model [kafka]
Posted by "clolov (via GitHub)" <gi...@apache.org>.
clolov commented on PR #22398:
URL: https://github.com/apache/kafka/pull/22398#issuecomment-4563372773
Turning this into a Draft for the time being
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] MINOR: A starting point for a formal security model [kafka]
Posted by "clolov (via GitHub)" <gi...@apache.org>.
clolov commented on code in PR #22398:
URL: https://github.com/apache/kafka/pull/22398#discussion_r3387124160
##########
docs/security/security-model.md:
##########
@@ -0,0 +1,162 @@
+---
+title: Security Model
+description: Apache Kafka Security Model
+weight: 8
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+## Things You Need To Know
+
+- **Security is off by default.** A freshly-installed Apache Kafka cluster accepts unauthenticated `PLAINTEXT` connections on every listener and applies no authorization. This is appropriate only for closed test environments. Production deployments **must** explicitly configure authentication, authorization, and transport encryption before being exposed to any untrusted network.
+- **Apache Kafka assumes a trusted operator.** Anyone with shell access to a broker, controller, or the underlying disks can read every topic, forge any principal, and rewrite ACLs. The security model protects messages in transit and arbitrates client access — it does not defend brokers from their own administrators.
+- **Apache Kafka assumes a trusted broker fleet.** Brokers and KRaft controllers exchange records, replication state, and metadata over the inter-broker and controller listeners. Any host that can authenticate on those listeners is effectively part of the cluster's trust boundary.
+- **The data plane and the control plane have different exposure.** Producer/consumer traffic, the Admin API, and JMX each have distinct authentication and authorization stories. Operators must configure them independently — securing one does not secure the others.
+- **Apache Kafka does not encrypt data at rest.** Log segments, index files, and snapshots are written as plain bytes. At-rest confidentiality is the responsibility of the underlying filesystem, block device, or message-level encryption performed by producers.
+- **Reporting vulnerabilities.** Suspected security issues should be reported privately to `security@kafka.apache.org` per the [ASF security process](https://www.apache.org/security/). Do not file public JIRA tickets, GitHub issues, or mailing-list posts for unpatched vulnerabilities.
+
+## Listeners and the Network Boundary
+
+Apache Kafka brokers expose one or more **listeners**, each with an independent security configuration selected by `listener.security.protocol.map`. The four protocols are:
+
+| Protocol | Authentication | Encryption |
+|------------------|------------------------|------------|
+| `PLAINTEXT` | None | None |
+| `SSL` | Optional mTLS | TLS |
+| `SASL_PLAINTEXT` | SASL | None |
+| `SASL_SSL` | SASL (+ optional mTLS) | TLS |
+
+`inter.broker.listener.name` and `controller.listener.names` select which listeners carry replication and KRaft traffic respectively. A common pattern is to keep these on a dedicated internal listener (`SASL_SSL` or `SSL`) that is firewalled off from clients, so that a compromise of a client-facing listener cannot impersonate a broker.
+
+Operators should:
+
+1. Bind external listeners only to interfaces reachable by intended clients.
+2. Treat `advertised.listeners` as part of the security configuration — clients connect to whatever the broker advertises after the initial metadata fetch.
+3. Never expose the controller listener to client networks.
+
+## Authentication
+
+Apache Kafka supports two complementary authentication mechanisms; either may be used, and both can be combined on a `SASL_SSL` listener.
+
+### TLS Client Authentication (mTLS)
+
+When `ssl.client.auth` is `required` on a TLS listener, the client's X.509 certificate is verified against the broker's truststore. The authenticated principal is derived from the certificate's distinguished name via `ssl.principal.mapping.rules` (or a custom `KafkaPrincipalBuilder`).
+
+mTLS is the recommended mechanism for broker-to-broker and controller-to-broker traffic, because it requires no shared password material and rotates with the rest of the PKI.
+
+### SASL
+
+Apache Kafka ships with five SASL mechanisms, enabled per-listener via `sasl.enabled.mechanisms`:
+
+- **`GSSAPI`** — Kerberos. Recommended for environments that already operate a KDC; principals and credentials are managed externally.
+- **`SCRAM-SHA-256` / `SCRAM-SHA-512`** — Salted challenge/response with credentials stored in the cluster metadata. Credentials are managed with `kafka-configs.sh --alter --add-config 'SCRAM-SHA-512=...'`.
+- **`OAUTHBEARER`** — OAuth 2.0 bearer tokens, suitable for integration with an identity provider. The default unsecured implementation is for testing only; production deployments must configure a JWKS endpoint and validator.
+- **`PLAIN`** — Username/password sent in cleartext over the SASL channel. Acceptable only inside a `SASL_SSL` listener; never use it with `SASL_PLAINTEXT`.
+
+#### Delegation Tokens
+
+Once a client has authenticated via SASL or mTLS, it can request a short-lived **delegation token** that is then used as a `SCRAM-SHA-256` credential for subsequent connections. Delegation tokens are intended for distributed frameworks (Spark, Flink, Connect workers) that need to fan out to many tasks without distributing the original credential. Tokens inherit the requester's principal and ACLs, expire on a fixed schedule (`delegation.token.expiry.time.ms`), and can be invalidated by the owner.
+
+## Authorization
+
+Authentication establishes a `KafkaPrincipal`; authorization decides what that principal may do. Authorization is performed by the configured `authorizer.class.name`. Apache Kafka ships `org.apache.kafka.metadata.authorizer.StandardAuthorizer` for KRaft clusters.
+
+ACLs are tuples of `(principal, host, operation, resource pattern, permission)`. Resources are typed (`Topic`, `Group`, `Cluster`, `TransactionalId`, `DelegationToken`, `User`) and patterns may be `LITERAL` or `PREFIXED`.
+
+Defaults worth understanding:
+
+- If no authorizer is configured, **all authenticated principals have full access**. Configuring authentication without an authorizer provides identity but no authorization.
+- If an authorizer is configured but no ACLs match, access is **denied**. The exception is the principals listed in `super.users`, which bypass ACL checks entirely; treat that list as you would a root password.
+- `allow.everyone.if.no.acl.found=true` reverses the default-deny behaviour for resources that have no ACLs at all. It is a transitional aid for adding authorization to existing clusters and should not remain set in steady state.
+
+ACLs are managed with `kafka-acls.sh` or the AdminClient `createAcls`/`deleteAcls` APIs, which are themselves gated by ACLs on the `Cluster` resource.
+
+## Encryption in Transit
+
+TLS is configured per-listener via the standard `ssl.*` properties (`ssl.keystore.*`, `ssl.truststore.*`, `ssl.protocol`, `ssl.cipher.suites`, `ssl.enabled.protocols`). Recommendations:
+
+- Disable TLS versions below 1.2; prefer 1.3 where the JDK supports it.
+- Use distinct keystores for the inter-broker listener and any client-facing listener so that a leaked client-facing key cannot impersonate a broker.
+- Set `ssl.endpoint.identification.algorithm=https` on clients (the default since 2.0) so that the broker's certificate must match its hostname.
+- Rotate keystores using the dynamic broker configuration mechanism (`kafka-configs.sh --entity-type brokers --alter --add-config ...`) to avoid restarts.
+
+Kafka Connect, MirrorMaker 2, and Kafka Streams all consume the same `ssl.*` and `sasl.*` client configs — securing the broker is necessary but not sufficient.
+
+## Encryption at Rest
+
+Apache Kafka does not encrypt log segments, indexes, snapshots, or controller metadata on disk. Operators who require at-rest confidentiality have three options, in increasing order of cost:
+
+1. **Filesystem or block-device encryption** Transparent to Kafka; protects against disk theft and misdirected backups but not against anyone with broker login.
+2. **Message-level encryption.** Producers encrypt payloads (and optionally headers) before `send()`; consumers decrypt. Keys are managed by an external KMS. This is the only option that protects records from broker operators, but it precludes broker-side features that read payloads (e.g. Streams aggregations on the encrypted field).
+3. **Tiered storage** with a remote store that performs its own encryption.
+
+## Audit Logging
+
+Apache Kafka emits authorizer decisions to the `kafka.authorizer.logger` log4j logger. Setting this logger to `INFO` records every denied request; `DEBUG` records every allowed request as well. In regulated environments this log should be shipped to durable, append-only storage off-broker. There is no built-in tamper-evident audit trail.
+
+The request log (`kafka.request.logger`) provides finer detail on individual API calls and is useful for forensic investigation, but it is verbose and not enabled by default.
+
+## Secrets in Configuration
+
+Broker, client, and Connect properties files contain keystore passwords, SASL credentials, and similar secrets. Apache Kafka supports indirect references through `ConfigProvider` implementations (`FileConfigProvider`, `DirectoryConfigProvider`, or custom providers). Use them rather than embedding cleartext secrets in version-controlled configuration. For the file-based providers, set `allowed.paths` to the specific directories that hold those secrets so that a malicious or mistaken configuration cannot coerce the provider into reading arbitrary files elsewhere on the host. Sensitive dynamic broker configurations are encrypted at rest in the metadata log using `password.encoder.secret`; rotating that secret requires `password.encoder.old.secret` and a rolling restart.
+
+## Component-Specific Notes
+
+- **JMX.** Brokers expose operational metrics over JMX. JMX is an administrators/operators-only interface and must never be exposed to actual users. It is unauthenticated by default and should either be disabled, bound to localhost with an exporter alongside, or configured with `com.sun.management.jmxremote.authenticate=true` and TLS.
+
+The components built on top of the brokers and clients have their own security models, covered on separate pages:
Review Comment:
Nice catch again, I had a separate section about Tiered Storage as well, but eventually decided to leave it folded in the main part. This is a remnant and I will remove it.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] MINOR: A starting point for a formal security model [kafka]
Posted by "clolov (via GitHub)" <gi...@apache.org>.
clolov commented on code in PR #22398:
URL: https://github.com/apache/kafka/pull/22398#discussion_r3324692122
##########
docs/security/security-model.md:
##########
@@ -0,0 +1,132 @@
+---
+title: Security Model
+description: Apache Kafka Security Model
+weight: 8
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+## Things You Need To Know
+
+- **Security is off by default.** A freshly-installed Apache Kafka cluster accepts unauthenticated `PLAINTEXT` connections on every listener and applies no authorization. This is appropriate only for closed test environments. Production deployments **must** explicitly configure authentication, authorization, and transport encryption before being exposed to any untrusted network.
+- **Apache Kafka assumes a trusted operator.** Anyone with shell access to a broker, controller, or the underlying disks can read every topic, forge any principal, and rewrite ACLs. The security model protects messages in transit and arbitrates client access — it does not defend brokers from their own administrators.
+- **Apache Kafka assumes a trusted broker fleet.** Brokers and KRaft controllers exchange records, replication state, and metadata over the inter-broker and controller listeners. Any host that can authenticate on those listeners is effectively part of the cluster's trust boundary.
+- **The data plane and the control plane have different exposure.** Producer/consumer traffic, the Admin API, the Kafka Connect REST API, and JMX each have distinct authentication and authorization stories. Operators must configure them independently — securing one does not secure the others.
+- **Apache Kafka does not encrypt data at rest.** Log segments, index files, and snapshots are written as plain bytes. At-rest confidentiality is the responsibility of the underlying filesystem, block device, or message-level encryption performed by producers.
+- **Reporting vulnerabilities.** Suspected security issues should be reported privately to `security@kafka.apache.org` per the [ASF security process](https://www.apache.org/security/). Do not file public JIRA tickets, GitHub issues, or mailing-list posts for unpatched vulnerabilities.
+
+## Listeners and the Network Boundary
+
+Apache Kafka brokers expose one or more **listeners**, each with an independent security configuration selected by `listener.security.protocol.map`. The four protocols are:
+
+| Protocol | Authentication | Encryption |
+|------------------|------------------------|------------|
+| `PLAINTEXT` | None | None |
+| `SSL` | Optional mTLS | TLS |
+| `SASL_PLAINTEXT` | SASL | None |
+| `SASL_SSL` | SASL (+ optional mTLS) | TLS |
+
+`inter.broker.listener.name` and `controller.listener.names` select which listeners carry replication and KRaft traffic respectively. A common pattern is to keep these on a dedicated internal listener (`SASL_SSL` or `SSL`) that is firewalled off from clients, so that a compromise of a client-facing listener cannot impersonate a broker.
+
+Operators should:
+
+1. Bind external listeners only to interfaces reachable by intended clients.
+2. Treat `advertised.listeners` as part of the security configuration — clients connect to whatever the broker advertises after the initial metadata fetch.
+3. Never expose the controller listener to client networks.
+
+## Authentication
+
+Apache Kafka supports two complementary authentication mechanisms; either may be used, and both can be combined on a `SASL_SSL` listener.
+
+### TLS Client Authentication (mTLS)
+
+When `ssl.client.auth` is `required` on a TLS listener, the client's X.509 certificate is verified against the broker's truststore. The authenticated principal is derived from the certificate's distinguished name via `ssl.principal.mapping.rules` (or a custom `KafkaPrincipalBuilder`).
+
+mTLS is the recommended mechanism for broker-to-broker and controller-to-broker traffic, because it requires no shared password material and rotates with the rest of the PKI.
+
+### SASL
+
+Apache Kafka ships with five SASL mechanisms, enabled per-listener via `sasl.enabled.mechanisms`:
+
+- **`GSSAPI`** — Kerberos. Recommended for environments that already operate a KDC; principals and credentials are managed externally.
+- **`SCRAM-SHA-256` / `SCRAM-SHA-512`** — Salted challenge/response with credentials stored in the cluster metadata. Credentials are managed with `kafka-configs.sh --alter --add-config 'SCRAM-SHA-512=...'`.
+- **`OAUTHBEARER`** — OAuth 2.0 bearer tokens, suitable for integration with an identity provider. The default unsecured implementation is for testing only; production deployments must configure a JWKS endpoint and validator.
+- **`PLAIN`** — Username/password sent in cleartext over the SASL channel. Acceptable only inside a `SASL_SSL` listener; never use it with `SASL_PLAINTEXT`.
+
+#### Delegation Tokens
+
+Once a client has authenticated via SASL or mTLS, it can request a short-lived **delegation token** that is then used as a `SCRAM-SHA-256` credential for subsequent connections. Delegation tokens are intended for distributed frameworks (Spark, Flink, Connect workers) that need to fan out to many tasks without distributing the original credential. Tokens inherit the requester's principal and ACLs, expire on a fixed schedule (`delegation.token.expiry.time.ms`), and can be invalidated by the owner.
+
+## Authorization
+
+Authentication establishes a `KafkaPrincipal`; authorization decides what that principal may do. Authorization is performed by the configured `authorizer.class.name`. Apache Kafka ships `org.apache.kafka.metadata.authorizer.StandardAuthorizer` for KRaft clusters.
+
+ACLs are tuples of `(principal, host, operation, resource pattern, permission)`. Resources are typed (`Topic`, `Group`, `Cluster`, `TransactionalId`, `DelegationToken`, `User`) and patterns may be `LITERAL` or `PREFIXED`.
+
+Defaults worth understanding:
+
+- If no authorizer is configured, **all authenticated principals have full access**. Configuring authentication without an authorizer provides identity but no authorization.
+- If an authorizer is configured but no ACLs match, access is **denied**. The exception is the principals listed in `super.users`, which bypass ACL checks entirely; treat that list as you would a root password.
+- `allow.everyone.if.no.acl.found=true` reverses the default-deny behaviour for resources that have no ACLs at all. It is a transitional aid for adding authorization to existing clusters and should not remain set in steady state.
+
+ACLs are managed with `kafka-acls.sh` or the AdminClient `createAcls`/`deleteAcls` APIs, which are themselves gated by ACLs on the `Cluster` resource.
+
+## Encryption in Transit
+
+TLS is configured per-listener via the standard `ssl.*` properties (`ssl.keystore.*`, `ssl.truststore.*`, `ssl.protocol`, `ssl.cipher.suites`, `ssl.enabled.protocols`). Recommendations:
+
+- Disable TLS versions below 1.2; prefer 1.3 where the JDK supports it.
+- Use distinct keystores for the inter-broker listener and any client-facing listener so that a leaked client-facing key cannot impersonate a broker.
+- Set `ssl.endpoint.identification.algorithm=https` on clients (the default since 2.0) so that the broker's certificate must match its hostname.
+- Rotate keystores using the dynamic broker configuration mechanism (`kafka-configs.sh --entity-type brokers --alter --add-config ...`) to avoid restarts.
+
+Kafka Connect, MirrorMaker 2, Kafka Streams, and the Schema Registry-style ecosystem tools all consume the same `ssl.*` and `sasl.*` client configs — securing the broker is necessary but not sufficient.
+
+## Encryption at Rest
+
+Apache Kafka does not encrypt log segments, indexes, snapshots, or controller metadata on disk. Operators who require at-rest confidentiality have three options, in increasing order of cost:
+
+1. **Filesystem or block-device encryption** Transparent to Kafka; protects against disk theft and misdirected backups but not against anyone with broker login.
+2. **Message-level encryption.** Producers encrypt payloads (and optionally headers) before `send()`; consumers decrypt. Keys are managed by an external KMS. This is the only option that protects records from broker operators, but it precludes broker-side features that read payloads (e.g. Streams aggregations on the encrypted field).
+3. **Tiered storage** with a remote store that performs its own encryption.
+
+## Audit Logging
+
+Apache Kafka emits authorizer decisions to the `kafka.authorizer.logger` log4j logger. Setting this logger to `INFO` records every denied request; `DEBUG` records every allowed request as well. In regulated environments this log should be shipped to durable, append-only storage off-broker. There is no built-in tamper-evident audit trail; integrate with the host's auditing pipeline.
+
+The request log (`kafka.request.logger`) provides finer detail on individual API calls and is useful for forensic investigation, but it is verbose and not enabled by default.
+
+## Secrets in Configuration
+
+Broker, client, and Connect properties files contain keystore passwords, SASL credentials, and similar secrets. Apache Kafka supports indirect references through `ConfigProvider` implementations (`FileConfigProvider`, `DirectoryConfigProvider`, or custom providers). Use them rather than embedding cleartext secrets in version-controlled configuration. Sensitive dynamic broker configurations are encrypted at rest in the metadata log using `password.encoder.secret`; rotating that secret requires `password.encoder.old.secret` and a rolling restart.
+
+## Component-Specific Notes
+
+- **Kafka Connect.** The REST API is unauthenticated by default; enable the built-in basic auth extension or front it with a reverse proxy. Connector configurations may contain credentials for external systems and should be stored via a `ConfigProvider`. Connect workers authenticate to the Kafka cluster as a single principal — partition that principal's ACLs by topic prefix per connector.
+- **Kafka Streams.** A Streams application authenticates as one principal that needs ACLs covering its source topics, internal repartition/changelog topics (typically `<application.id>-*`), and the consumer group `<application.id>`.
+- **MirrorMaker 2.** Replicates across security domains; configure `source.cluster.*` and `target.cluster.*` independently and never tunnel cleartext replication across an untrusted network.
+- **JMX.** Brokers expose operational metrics over JMX. JMX is unauthenticated by default and should either be disabled, bound to localhost with an exporter alongside, or configured with `com.sun.management.jmxremote.authenticate=true` and TLS.
+
Review Comment:
Great point, I will expand on this as well!
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] MINOR: A starting point for a formal security model [kafka]
Posted by "mimaison (via GitHub)" <gi...@apache.org>.
mimaison commented on code in PR #22398:
URL: https://github.com/apache/kafka/pull/22398#discussion_r3396727404
##########
docs/security/security-model.md:
##########
@@ -0,0 +1,169 @@
+---
+title: Security Model
+description: Apache Kafka Security Model
+weight: 8
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+## Things You Need To Know
+
+- **Security is off by default.** A freshly-installed Apache Kafka cluster accepts unauthenticated `PLAINTEXT` connections on every listener and applies no authorization. This is appropriate only for closed test environments. Production deployments **must** explicitly configure authentication, authorization, and transport encryption before being exposed to any untrusted network.
+- **Apache Kafka assumes a trusted operator.** Anyone with shell access to a broker, controller, or the underlying disks can read every topic, forge any principal, and rewrite ACLs. The security model protects messages in transit and arbitrates client access — it does not defend brokers from their own administrators.
+- **Apache Kafka assumes a trusted broker fleet.** Brokers and KRaft controllers exchange records, replication state, and metadata over the inter-broker and controller listeners. Any host that can authenticate on those listeners is effectively part of the cluster's trust boundary.
+- **Apache Kafka trusts its JVM and classpath.** JARs on a process's classpath run with that process's full privileges. Placing code on the classpath — or configuring a component to load it — is equivalent to trusting that code; the model assumes no hostile JARs are present.
+- **The data plane and the control plane have different exposure.** Producer/consumer traffic, the Admin API, and JMX each have distinct authentication and authorization stories. Operators must configure them independently — securing one does not secure the others.
+- **Apache Kafka does not encrypt data at rest.** Log segments, index files, and snapshots are written as plain bytes. At-rest confidentiality is the responsibility of the underlying filesystem, block device, or message-level encryption performed by producers.
+- **Reporting vulnerabilities.** Suspected security issues should be reported privately to `security@kafka.apache.org` per the [ASF security process](https://www.apache.org/security/). Do not file public JIRA tickets, GitHub issues, or mailing-list posts for unpatched vulnerabilities.
+
+## Listeners and the Network Boundary
+
+Apache Kafka brokers expose one or more **listeners**, each with an independent security configuration selected by `listener.security.protocol.map`. The four protocols are:
+
+| Protocol | Authentication | Encryption |
+|------------------|------------------------|------------|
+| `PLAINTEXT` | None | None |
+| `SSL` | Optional mTLS | TLS |
+| `SASL_PLAINTEXT` | SASL | None |
+| `SASL_SSL` | SASL (+ optional mTLS) | TLS |
+
+`inter.broker.listener.name` and `controller.listener.names` select which listeners carry replication and KRaft traffic respectively. A common pattern is to keep these on a dedicated internal listener (`SASL_SSL` or `SSL`) that is firewalled off from clients, so that a compromise of a client-facing listener cannot impersonate a broker.
+
+Operators should:
+
+1. Bind external listeners only to interfaces reachable by intended clients.
+2. Treat `advertised.listeners` as part of the security configuration — clients connect to whatever the broker advertises after the initial metadata fetch.
+3. Never expose the controller listener to client networks.
+
+## Authentication
+
+Apache Kafka supports two complementary authentication mechanisms; either may be used, and both can be combined on a `SASL_SSL` listener.
+
+### TLS Client Authentication (mTLS)
+
+When `ssl.client.auth` is `required` on a TLS listener, the client's X.509 certificate is verified against the broker's truststore. The authenticated principal is derived from the certificate's distinguished name via `ssl.principal.mapping.rules` (or a custom `KafkaPrincipalBuilder`).
+
+mTLS is the recommended mechanism for broker-to-broker and controller-to-broker traffic, because it requires no shared password material and rotates with the rest of the PKI.
+
+### SASL
+
+Apache Kafka ships with five SASL mechanisms, enabled per-listener via `sasl.enabled.mechanisms`:
+
+- **`GSSAPI`** — Kerberos. Recommended for environments that already operate a KDC; principals and credentials are managed externally.
+- **`SCRAM-SHA-256` / `SCRAM-SHA-512`** — Salted challenge/response with credentials stored in the cluster metadata. Credentials are managed with `kafka-configs.sh --alter --add-config 'SCRAM-SHA-512=...'`.
+- **`OAUTHBEARER`** — OAuth 2.0 bearer tokens, suitable for integration with an identity provider. The default unsecured implementation is for testing only; production deployments must configure a JWKS endpoint and validator.
+- **`PLAIN`** — Username/password sent in cleartext over the SASL channel. Acceptable only inside a `SASL_SSL` listener; never use it with `SASL_PLAINTEXT`.
+
+#### Delegation Tokens
+
+Once a client has authenticated via SASL or mTLS, it can request a short-lived **delegation token** that is then used as a `SCRAM-SHA-256` credential for subsequent connections. Delegation tokens are intended for distributed frameworks (Spark, Flink, Connect workers) that need to fan out to many tasks without distributing the original credential. Tokens inherit the requester's principal and ACLs, expire on a fixed schedule (`delegation.token.expiry.time.ms`), and can be invalidated by the owner.
+
+## Authorization
+
+Authentication establishes a `KafkaPrincipal`; authorization decides what that principal may do. Authorization is performed by the configured `authorizer.class.name`. Apache Kafka ships `org.apache.kafka.metadata.authorizer.StandardAuthorizer` for KRaft clusters.
+
+ACLs are tuples of `(principal, host, operation, resource pattern, permission)`. Resources are typed (`Topic`, `Group`, `Cluster`, `TransactionalId`, `DelegationToken`, `User`) and patterns may be `LITERAL` or `PREFIXED`.
+
+Defaults worth understanding:
+
+- If no authorizer is configured, **all authenticated principals have full access**. Configuring authentication without an authorizer provides identity but no authorization.
+- If an authorizer is configured but no ACLs match, access is **denied**. The exception is the principals listed in `super.users`, which bypass ACL checks entirely; treat that list as you would a root password.
+- `allow.everyone.if.no.acl.found=true` reverses the default-deny behaviour for resources that have no ACLs at all. It is a transitional aid for adding authorization to existing clusters and should not remain set in steady state.
+
+ACLs are managed with `kafka-acls.sh` or the AdminClient `createAcls`/`deleteAcls` APIs, which are themselves gated by ACLs on the `Cluster` resource.
+
+## Encryption in Transit
+
+TLS is configured per-listener via the standard `ssl.*` properties (`ssl.keystore.*`, `ssl.truststore.*`, `ssl.protocol`, `ssl.cipher.suites`, `ssl.enabled.protocols`). Recommendations:
+
+- Disable TLS versions below 1.2; prefer 1.3 where the JDK supports it.
+- Use distinct keystores for the inter-broker listener and any client-facing listener so that a leaked client-facing key cannot impersonate a broker.
+- Set `ssl.endpoint.identification.algorithm=https` on clients (the default since 2.0) so that the broker's certificate must match its hostname.
+- Rotate keystores using the dynamic broker configuration mechanism (`kafka-configs.sh --entity-type brokers --alter --add-config ...`) to avoid restarts.
+
+Kafka Connect, MirrorMaker 2, and Kafka Streams all consume the same `ssl.*` and `sasl.*` client configs — securing the broker is necessary but not sufficient.
+
+## Encryption at Rest
+
+Apache Kafka does not encrypt log segments, indexes, snapshots, or controller metadata on disk. Operators who require at-rest confidentiality have three options, in increasing order of cost:
+
+1. **Filesystem or block-device encryption** Transparent to Kafka; protects against disk theft and misdirected backups but not against anyone with broker login.
+2. **Message-level encryption.** Producers encrypt payloads (and optionally headers) before `send()`; consumers decrypt. Keys are managed by an external KMS. This is the only option that protects records from broker operators, but it precludes broker-side features that read payloads (e.g. Streams aggregations on the encrypted field).
+3. **Tiered storage** with a remote store that performs its own encryption.
+
+## Audit Logging
+
+Apache Kafka emits authorizer decisions to the `kafka.authorizer.logger` log4j logger. Setting this logger to `INFO` records every denied request; `DEBUG` records every allowed request as well. In regulated environments this log should be shipped to durable, append-only storage off-broker. There is no built-in tamper-evident audit trail.
+
+The request log (`kafka.request.logger`) provides finer detail on individual API calls and is useful for forensic investigation, but it is verbose and not enabled by default.
+
+## Secrets in Configuration
+
+Broker, client, and Connect properties files contain keystore passwords, SASL credentials, and similar secrets. Apache Kafka supports indirect references through `ConfigProvider` implementations (`FileConfigProvider`, `DirectoryConfigProvider`, or custom providers). Use them rather than embedding cleartext secrets in version-controlled configuration. For the file-based providers, set `allowed.paths` to the specific directories that hold those secrets so that a malicious or mistaken configuration cannot coerce the provider into reading arbitrary files elsewhere on the host. Sensitive dynamic broker configurations are encrypted at rest in the metadata log using `password.encoder.secret`; rotating that secret requires `password.encoder.old.secret` and a rolling restart.
+
Review Comment:
Should we have a statement about pluggable interfaces? All our components expose plugins. It may be obvious but these grant code execution, so only install and use plugins that you fully trust
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] MINOR: A starting point for a formal security model [kafka]
Posted by "mimaison (via GitHub)" <gi...@apache.org>.
mimaison commented on code in PR #22398:
URL: https://github.com/apache/kafka/pull/22398#discussion_r3382324144
##########
docs/security/security-model.md:
##########
@@ -0,0 +1,162 @@
+---
+title: Security Model
+description: Apache Kafka Security Model
+weight: 8
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+## Things You Need To Know
+
+- **Security is off by default.** A freshly-installed Apache Kafka cluster accepts unauthenticated `PLAINTEXT` connections on every listener and applies no authorization. This is appropriate only for closed test environments. Production deployments **must** explicitly configure authentication, authorization, and transport encryption before being exposed to any untrusted network.
+- **Apache Kafka assumes a trusted operator.** Anyone with shell access to a broker, controller, or the underlying disks can read every topic, forge any principal, and rewrite ACLs. The security model protects messages in transit and arbitrates client access — it does not defend brokers from their own administrators.
+- **Apache Kafka assumes a trusted broker fleet.** Brokers and KRaft controllers exchange records, replication state, and metadata over the inter-broker and controller listeners. Any host that can authenticate on those listeners is effectively part of the cluster's trust boundary.
+- **The data plane and the control plane have different exposure.** Producer/consumer traffic, the Admin API, and JMX each have distinct authentication and authorization stories. Operators must configure them independently — securing one does not secure the others.
+- **Apache Kafka does not encrypt data at rest.** Log segments, index files, and snapshots are written as plain bytes. At-rest confidentiality is the responsibility of the underlying filesystem, block device, or message-level encryption performed by producers.
+- **Reporting vulnerabilities.** Suspected security issues should be reported privately to `security@kafka.apache.org` per the [ASF security process](https://www.apache.org/security/). Do not file public JIRA tickets, GitHub issues, or mailing-list posts for unpatched vulnerabilities.
+
+## Listeners and the Network Boundary
+
+Apache Kafka brokers expose one or more **listeners**, each with an independent security configuration selected by `listener.security.protocol.map`. The four protocols are:
+
+| Protocol | Authentication | Encryption |
+|------------------|------------------------|------------|
+| `PLAINTEXT` | None | None |
+| `SSL` | Optional mTLS | TLS |
+| `SASL_PLAINTEXT` | SASL | None |
+| `SASL_SSL` | SASL (+ optional mTLS) | TLS |
+
+`inter.broker.listener.name` and `controller.listener.names` select which listeners carry replication and KRaft traffic respectively. A common pattern is to keep these on a dedicated internal listener (`SASL_SSL` or `SSL`) that is firewalled off from clients, so that a compromise of a client-facing listener cannot impersonate a broker.
+
+Operators should:
+
+1. Bind external listeners only to interfaces reachable by intended clients.
+2. Treat `advertised.listeners` as part of the security configuration — clients connect to whatever the broker advertises after the initial metadata fetch.
+3. Never expose the controller listener to client networks.
+
+## Authentication
+
+Apache Kafka supports two complementary authentication mechanisms; either may be used, and both can be combined on a `SASL_SSL` listener.
+
+### TLS Client Authentication (mTLS)
+
+When `ssl.client.auth` is `required` on a TLS listener, the client's X.509 certificate is verified against the broker's truststore. The authenticated principal is derived from the certificate's distinguished name via `ssl.principal.mapping.rules` (or a custom `KafkaPrincipalBuilder`).
+
+mTLS is the recommended mechanism for broker-to-broker and controller-to-broker traffic, because it requires no shared password material and rotates with the rest of the PKI.
+
+### SASL
+
+Apache Kafka ships with five SASL mechanisms, enabled per-listener via `sasl.enabled.mechanisms`:
+
+- **`GSSAPI`** — Kerberos. Recommended for environments that already operate a KDC; principals and credentials are managed externally.
+- **`SCRAM-SHA-256` / `SCRAM-SHA-512`** — Salted challenge/response with credentials stored in the cluster metadata. Credentials are managed with `kafka-configs.sh --alter --add-config 'SCRAM-SHA-512=...'`.
+- **`OAUTHBEARER`** — OAuth 2.0 bearer tokens, suitable for integration with an identity provider. The default unsecured implementation is for testing only; production deployments must configure a JWKS endpoint and validator.
+- **`PLAIN`** — Username/password sent in cleartext over the SASL channel. Acceptable only inside a `SASL_SSL` listener; never use it with `SASL_PLAINTEXT`.
+
+#### Delegation Tokens
+
+Once a client has authenticated via SASL or mTLS, it can request a short-lived **delegation token** that is then used as a `SCRAM-SHA-256` credential for subsequent connections. Delegation tokens are intended for distributed frameworks (Spark, Flink, Connect workers) that need to fan out to many tasks without distributing the original credential. Tokens inherit the requester's principal and ACLs, expire on a fixed schedule (`delegation.token.expiry.time.ms`), and can be invalidated by the owner.
+
+## Authorization
+
+Authentication establishes a `KafkaPrincipal`; authorization decides what that principal may do. Authorization is performed by the configured `authorizer.class.name`. Apache Kafka ships `org.apache.kafka.metadata.authorizer.StandardAuthorizer` for KRaft clusters.
+
+ACLs are tuples of `(principal, host, operation, resource pattern, permission)`. Resources are typed (`Topic`, `Group`, `Cluster`, `TransactionalId`, `DelegationToken`, `User`) and patterns may be `LITERAL` or `PREFIXED`.
+
+Defaults worth understanding:
+
+- If no authorizer is configured, **all authenticated principals have full access**. Configuring authentication without an authorizer provides identity but no authorization.
+- If an authorizer is configured but no ACLs match, access is **denied**. The exception is the principals listed in `super.users`, which bypass ACL checks entirely; treat that list as you would a root password.
+- `allow.everyone.if.no.acl.found=true` reverses the default-deny behaviour for resources that have no ACLs at all. It is a transitional aid for adding authorization to existing clusters and should not remain set in steady state.
+
+ACLs are managed with `kafka-acls.sh` or the AdminClient `createAcls`/`deleteAcls` APIs, which are themselves gated by ACLs on the `Cluster` resource.
+
+## Encryption in Transit
+
+TLS is configured per-listener via the standard `ssl.*` properties (`ssl.keystore.*`, `ssl.truststore.*`, `ssl.protocol`, `ssl.cipher.suites`, `ssl.enabled.protocols`). Recommendations:
+
+- Disable TLS versions below 1.2; prefer 1.3 where the JDK supports it.
+- Use distinct keystores for the inter-broker listener and any client-facing listener so that a leaked client-facing key cannot impersonate a broker.
+- Set `ssl.endpoint.identification.algorithm=https` on clients (the default since 2.0) so that the broker's certificate must match its hostname.
+- Rotate keystores using the dynamic broker configuration mechanism (`kafka-configs.sh --entity-type brokers --alter --add-config ...`) to avoid restarts.
+
+Kafka Connect, MirrorMaker 2, and Kafka Streams all consume the same `ssl.*` and `sasl.*` client configs — securing the broker is necessary but not sufficient.
+
+## Encryption at Rest
+
+Apache Kafka does not encrypt log segments, indexes, snapshots, or controller metadata on disk. Operators who require at-rest confidentiality have three options, in increasing order of cost:
+
+1. **Filesystem or block-device encryption** Transparent to Kafka; protects against disk theft and misdirected backups but not against anyone with broker login.
+2. **Message-level encryption.** Producers encrypt payloads (and optionally headers) before `send()`; consumers decrypt. Keys are managed by an external KMS. This is the only option that protects records from broker operators, but it precludes broker-side features that read payloads (e.g. Streams aggregations on the encrypted field).
+3. **Tiered storage** with a remote store that performs its own encryption.
+
+## Audit Logging
+
+Apache Kafka emits authorizer decisions to the `kafka.authorizer.logger` log4j logger. Setting this logger to `INFO` records every denied request; `DEBUG` records every allowed request as well. In regulated environments this log should be shipped to durable, append-only storage off-broker. There is no built-in tamper-evident audit trail.
+
+The request log (`kafka.request.logger`) provides finer detail on individual API calls and is useful for forensic investigation, but it is verbose and not enabled by default.
+
+## Secrets in Configuration
+
+Broker, client, and Connect properties files contain keystore passwords, SASL credentials, and similar secrets. Apache Kafka supports indirect references through `ConfigProvider` implementations (`FileConfigProvider`, `DirectoryConfigProvider`, or custom providers). Use them rather than embedding cleartext secrets in version-controlled configuration. For the file-based providers, set `allowed.paths` to the specific directories that hold those secrets so that a malicious or mistaken configuration cannot coerce the provider into reading arbitrary files elsewhere on the host. Sensitive dynamic broker configurations are encrypted at rest in the metadata log using `password.encoder.secret`; rotating that secret requires `password.encoder.old.secret` and a rolling restart.
+
+## Component-Specific Notes
+
+- **JMX.** Brokers expose operational metrics over JMX. JMX is an administrators/operators-only interface and must never be exposed to actual users. It is unauthenticated by default and should either be disabled, bound to localhost with an exporter alongside, or configured with `com.sun.management.jmxremote.authenticate=true` and TLS.
+
+The components built on top of the brokers and clients have their own security models, covered on separate pages:
Review Comment:
We don't have components built on top of brokers
##########
docs/security/security-model.md:
##########
@@ -0,0 +1,162 @@
+---
+title: Security Model
+description: Apache Kafka Security Model
+weight: 8
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+## Things You Need To Know
+
+- **Security is off by default.** A freshly-installed Apache Kafka cluster accepts unauthenticated `PLAINTEXT` connections on every listener and applies no authorization. This is appropriate only for closed test environments. Production deployments **must** explicitly configure authentication, authorization, and transport encryption before being exposed to any untrusted network.
+- **Apache Kafka assumes a trusted operator.** Anyone with shell access to a broker, controller, or the underlying disks can read every topic, forge any principal, and rewrite ACLs. The security model protects messages in transit and arbitrates client access — it does not defend brokers from their own administrators.
+- **Apache Kafka assumes a trusted broker fleet.** Brokers and KRaft controllers exchange records, replication state, and metadata over the inter-broker and controller listeners. Any host that can authenticate on those listeners is effectively part of the cluster's trust boundary.
+- **The data plane and the control plane have different exposure.** Producer/consumer traffic, the Admin API, and JMX each have distinct authentication and authorization stories. Operators must configure them independently — securing one does not secure the others.
+- **Apache Kafka does not encrypt data at rest.** Log segments, index files, and snapshots are written as plain bytes. At-rest confidentiality is the responsibility of the underlying filesystem, block device, or message-level encryption performed by producers.
+- **Reporting vulnerabilities.** Suspected security issues should be reported privately to `security@kafka.apache.org` per the [ASF security process](https://www.apache.org/security/). Do not file public JIRA tickets, GitHub issues, or mailing-list posts for unpatched vulnerabilities.
+
+## Listeners and the Network Boundary
+
+Apache Kafka brokers expose one or more **listeners**, each with an independent security configuration selected by `listener.security.protocol.map`. The four protocols are:
+
+| Protocol | Authentication | Encryption |
+|------------------|------------------------|------------|
+| `PLAINTEXT` | None | None |
+| `SSL` | Optional mTLS | TLS |
+| `SASL_PLAINTEXT` | SASL | None |
+| `SASL_SSL` | SASL (+ optional mTLS) | TLS |
+
+`inter.broker.listener.name` and `controller.listener.names` select which listeners carry replication and KRaft traffic respectively. A common pattern is to keep these on a dedicated internal listener (`SASL_SSL` or `SSL`) that is firewalled off from clients, so that a compromise of a client-facing listener cannot impersonate a broker.
+
+Operators should:
+
+1. Bind external listeners only to interfaces reachable by intended clients.
+2. Treat `advertised.listeners` as part of the security configuration — clients connect to whatever the broker advertises after the initial metadata fetch.
+3. Never expose the controller listener to client networks.
+
+## Authentication
+
+Apache Kafka supports two complementary authentication mechanisms; either may be used, and both can be combined on a `SASL_SSL` listener.
+
+### TLS Client Authentication (mTLS)
+
+When `ssl.client.auth` is `required` on a TLS listener, the client's X.509 certificate is verified against the broker's truststore. The authenticated principal is derived from the certificate's distinguished name via `ssl.principal.mapping.rules` (or a custom `KafkaPrincipalBuilder`).
+
+mTLS is the recommended mechanism for broker-to-broker and controller-to-broker traffic, because it requires no shared password material and rotates with the rest of the PKI.
+
+### SASL
+
+Apache Kafka ships with five SASL mechanisms, enabled per-listener via `sasl.enabled.mechanisms`:
+
+- **`GSSAPI`** — Kerberos. Recommended for environments that already operate a KDC; principals and credentials are managed externally.
+- **`SCRAM-SHA-256` / `SCRAM-SHA-512`** — Salted challenge/response with credentials stored in the cluster metadata. Credentials are managed with `kafka-configs.sh --alter --add-config 'SCRAM-SHA-512=...'`.
+- **`OAUTHBEARER`** — OAuth 2.0 bearer tokens, suitable for integration with an identity provider. The default unsecured implementation is for testing only; production deployments must configure a JWKS endpoint and validator.
+- **`PLAIN`** — Username/password sent in cleartext over the SASL channel. Acceptable only inside a `SASL_SSL` listener; never use it with `SASL_PLAINTEXT`.
+
+#### Delegation Tokens
+
+Once a client has authenticated via SASL or mTLS, it can request a short-lived **delegation token** that is then used as a `SCRAM-SHA-256` credential for subsequent connections. Delegation tokens are intended for distributed frameworks (Spark, Flink, Connect workers) that need to fan out to many tasks without distributing the original credential. Tokens inherit the requester's principal and ACLs, expire on a fixed schedule (`delegation.token.expiry.time.ms`), and can be invalidated by the owner.
+
+## Authorization
+
+Authentication establishes a `KafkaPrincipal`; authorization decides what that principal may do. Authorization is performed by the configured `authorizer.class.name`. Apache Kafka ships `org.apache.kafka.metadata.authorizer.StandardAuthorizer` for KRaft clusters.
+
+ACLs are tuples of `(principal, host, operation, resource pattern, permission)`. Resources are typed (`Topic`, `Group`, `Cluster`, `TransactionalId`, `DelegationToken`, `User`) and patterns may be `LITERAL` or `PREFIXED`.
+
+Defaults worth understanding:
+
+- If no authorizer is configured, **all authenticated principals have full access**. Configuring authentication without an authorizer provides identity but no authorization.
+- If an authorizer is configured but no ACLs match, access is **denied**. The exception is the principals listed in `super.users`, which bypass ACL checks entirely; treat that list as you would a root password.
+- `allow.everyone.if.no.acl.found=true` reverses the default-deny behaviour for resources that have no ACLs at all. It is a transitional aid for adding authorization to existing clusters and should not remain set in steady state.
+
+ACLs are managed with `kafka-acls.sh` or the AdminClient `createAcls`/`deleteAcls` APIs, which are themselves gated by ACLs on the `Cluster` resource.
+
+## Encryption in Transit
+
+TLS is configured per-listener via the standard `ssl.*` properties (`ssl.keystore.*`, `ssl.truststore.*`, `ssl.protocol`, `ssl.cipher.suites`, `ssl.enabled.protocols`). Recommendations:
+
+- Disable TLS versions below 1.2; prefer 1.3 where the JDK supports it.
+- Use distinct keystores for the inter-broker listener and any client-facing listener so that a leaked client-facing key cannot impersonate a broker.
+- Set `ssl.endpoint.identification.algorithm=https` on clients (the default since 2.0) so that the broker's certificate must match its hostname.
+- Rotate keystores using the dynamic broker configuration mechanism (`kafka-configs.sh --entity-type brokers --alter --add-config ...`) to avoid restarts.
+
+Kafka Connect, MirrorMaker 2, and Kafka Streams all consume the same `ssl.*` and `sasl.*` client configs — securing the broker is necessary but not sufficient.
+
+## Encryption at Rest
+
+Apache Kafka does not encrypt log segments, indexes, snapshots, or controller metadata on disk. Operators who require at-rest confidentiality have three options, in increasing order of cost:
+
+1. **Filesystem or block-device encryption** Transparent to Kafka; protects against disk theft and misdirected backups but not against anyone with broker login.
+2. **Message-level encryption.** Producers encrypt payloads (and optionally headers) before `send()`; consumers decrypt. Keys are managed by an external KMS. This is the only option that protects records from broker operators, but it precludes broker-side features that read payloads (e.g. Streams aggregations on the encrypted field).
+3. **Tiered storage** with a remote store that performs its own encryption.
+
+## Audit Logging
+
+Apache Kafka emits authorizer decisions to the `kafka.authorizer.logger` log4j logger. Setting this logger to `INFO` records every denied request; `DEBUG` records every allowed request as well. In regulated environments this log should be shipped to durable, append-only storage off-broker. There is no built-in tamper-evident audit trail.
+
+The request log (`kafka.request.logger`) provides finer detail on individual API calls and is useful for forensic investigation, but it is verbose and not enabled by default.
+
+## Secrets in Configuration
+
+Broker, client, and Connect properties files contain keystore passwords, SASL credentials, and similar secrets. Apache Kafka supports indirect references through `ConfigProvider` implementations (`FileConfigProvider`, `DirectoryConfigProvider`, or custom providers). Use them rather than embedding cleartext secrets in version-controlled configuration. For the file-based providers, set `allowed.paths` to the specific directories that hold those secrets so that a malicious or mistaken configuration cannot coerce the provider into reading arbitrary files elsewhere on the host. Sensitive dynamic broker configurations are encrypted at rest in the metadata log using `password.encoder.secret`; rotating that secret requires `password.encoder.old.secret` and a rolling restart.
+
+## Component-Specific Notes
+
+- **JMX.** Brokers expose operational metrics over JMX. JMX is an administrators/operators-only interface and must never be exposed to actual users. It is unauthenticated by default and should either be disabled, bound to localhost with an exporter alongside, or configured with `com.sun.management.jmxremote.authenticate=true` and TLS.
+
+The components built on top of the brokers and clients have their own security models, covered on separate pages:
+
+- [Kafka Connect](security-model-connect)
+- [Kafka Streams](security-model-streams)
+- [MirrorMaker 2](security-model-mirrormaker)
Review Comment:
I think we can just call it MirrorMaker now
##########
docs/security/security-model.md:
##########
@@ -0,0 +1,162 @@
+---
+title: Security Model
+description: Apache Kafka Security Model
+weight: 8
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+## Things You Need To Know
+
+- **Security is off by default.** A freshly-installed Apache Kafka cluster accepts unauthenticated `PLAINTEXT` connections on every listener and applies no authorization. This is appropriate only for closed test environments. Production deployments **must** explicitly configure authentication, authorization, and transport encryption before being exposed to any untrusted network.
+- **Apache Kafka assumes a trusted operator.** Anyone with shell access to a broker, controller, or the underlying disks can read every topic, forge any principal, and rewrite ACLs. The security model protects messages in transit and arbitrates client access — it does not defend brokers from their own administrators.
+- **Apache Kafka assumes a trusted broker fleet.** Brokers and KRaft controllers exchange records, replication state, and metadata over the inter-broker and controller listeners. Any host that can authenticate on those listeners is effectively part of the cluster's trust boundary.
+- **The data plane and the control plane have different exposure.** Producer/consumer traffic, the Admin API, and JMX each have distinct authentication and authorization stories. Operators must configure them independently — securing one does not secure the others.
+- **Apache Kafka does not encrypt data at rest.** Log segments, index files, and snapshots are written as plain bytes. At-rest confidentiality is the responsibility of the underlying filesystem, block device, or message-level encryption performed by producers.
+- **Reporting vulnerabilities.** Suspected security issues should be reported privately to `security@kafka.apache.org` per the [ASF security process](https://www.apache.org/security/). Do not file public JIRA tickets, GitHub issues, or mailing-list posts for unpatched vulnerabilities.
+
+## Listeners and the Network Boundary
+
+Apache Kafka brokers expose one or more **listeners**, each with an independent security configuration selected by `listener.security.protocol.map`. The four protocols are:
+
+| Protocol | Authentication | Encryption |
+|------------------|------------------------|------------|
+| `PLAINTEXT` | None | None |
+| `SSL` | Optional mTLS | TLS |
+| `SASL_PLAINTEXT` | SASL | None |
+| `SASL_SSL` | SASL (+ optional mTLS) | TLS |
+
+`inter.broker.listener.name` and `controller.listener.names` select which listeners carry replication and KRaft traffic respectively. A common pattern is to keep these on a dedicated internal listener (`SASL_SSL` or `SSL`) that is firewalled off from clients, so that a compromise of a client-facing listener cannot impersonate a broker.
+
+Operators should:
+
+1. Bind external listeners only to interfaces reachable by intended clients.
+2. Treat `advertised.listeners` as part of the security configuration — clients connect to whatever the broker advertises after the initial metadata fetch.
+3. Never expose the controller listener to client networks.
+
+## Authentication
+
+Apache Kafka supports two complementary authentication mechanisms; either may be used, and both can be combined on a `SASL_SSL` listener.
+
+### TLS Client Authentication (mTLS)
+
+When `ssl.client.auth` is `required` on a TLS listener, the client's X.509 certificate is verified against the broker's truststore. The authenticated principal is derived from the certificate's distinguished name via `ssl.principal.mapping.rules` (or a custom `KafkaPrincipalBuilder`).
+
+mTLS is the recommended mechanism for broker-to-broker and controller-to-broker traffic, because it requires no shared password material and rotates with the rest of the PKI.
+
+### SASL
+
+Apache Kafka ships with five SASL mechanisms, enabled per-listener via `sasl.enabled.mechanisms`:
+
+- **`GSSAPI`** — Kerberos. Recommended for environments that already operate a KDC; principals and credentials are managed externally.
+- **`SCRAM-SHA-256` / `SCRAM-SHA-512`** — Salted challenge/response with credentials stored in the cluster metadata. Credentials are managed with `kafka-configs.sh --alter --add-config 'SCRAM-SHA-512=...'`.
+- **`OAUTHBEARER`** — OAuth 2.0 bearer tokens, suitable for integration with an identity provider. The default unsecured implementation is for testing only; production deployments must configure a JWKS endpoint and validator.
+- **`PLAIN`** — Username/password sent in cleartext over the SASL channel. Acceptable only inside a `SASL_SSL` listener; never use it with `SASL_PLAINTEXT`.
+
+#### Delegation Tokens
+
+Once a client has authenticated via SASL or mTLS, it can request a short-lived **delegation token** that is then used as a `SCRAM-SHA-256` credential for subsequent connections. Delegation tokens are intended for distributed frameworks (Spark, Flink, Connect workers) that need to fan out to many tasks without distributing the original credential. Tokens inherit the requester's principal and ACLs, expire on a fixed schedule (`delegation.token.expiry.time.ms`), and can be invalidated by the owner.
+
+## Authorization
+
+Authentication establishes a `KafkaPrincipal`; authorization decides what that principal may do. Authorization is performed by the configured `authorizer.class.name`. Apache Kafka ships `org.apache.kafka.metadata.authorizer.StandardAuthorizer` for KRaft clusters.
+
+ACLs are tuples of `(principal, host, operation, resource pattern, permission)`. Resources are typed (`Topic`, `Group`, `Cluster`, `TransactionalId`, `DelegationToken`, `User`) and patterns may be `LITERAL` or `PREFIXED`.
+
+Defaults worth understanding:
+
+- If no authorizer is configured, **all authenticated principals have full access**. Configuring authentication without an authorizer provides identity but no authorization.
+- If an authorizer is configured but no ACLs match, access is **denied**. The exception is the principals listed in `super.users`, which bypass ACL checks entirely; treat that list as you would a root password.
+- `allow.everyone.if.no.acl.found=true` reverses the default-deny behaviour for resources that have no ACLs at all. It is a transitional aid for adding authorization to existing clusters and should not remain set in steady state.
+
+ACLs are managed with `kafka-acls.sh` or the AdminClient `createAcls`/`deleteAcls` APIs, which are themselves gated by ACLs on the `Cluster` resource.
+
+## Encryption in Transit
+
+TLS is configured per-listener via the standard `ssl.*` properties (`ssl.keystore.*`, `ssl.truststore.*`, `ssl.protocol`, `ssl.cipher.suites`, `ssl.enabled.protocols`). Recommendations:
+
+- Disable TLS versions below 1.2; prefer 1.3 where the JDK supports it.
+- Use distinct keystores for the inter-broker listener and any client-facing listener so that a leaked client-facing key cannot impersonate a broker.
+- Set `ssl.endpoint.identification.algorithm=https` on clients (the default since 2.0) so that the broker's certificate must match its hostname.
+- Rotate keystores using the dynamic broker configuration mechanism (`kafka-configs.sh --entity-type brokers --alter --add-config ...`) to avoid restarts.
+
+Kafka Connect, MirrorMaker 2, and Kafka Streams all consume the same `ssl.*` and `sasl.*` client configs — securing the broker is necessary but not sufficient.
+
+## Encryption at Rest
+
+Apache Kafka does not encrypt log segments, indexes, snapshots, or controller metadata on disk. Operators who require at-rest confidentiality have three options, in increasing order of cost:
+
+1. **Filesystem or block-device encryption** Transparent to Kafka; protects against disk theft and misdirected backups but not against anyone with broker login.
+2. **Message-level encryption.** Producers encrypt payloads (and optionally headers) before `send()`; consumers decrypt. Keys are managed by an external KMS. This is the only option that protects records from broker operators, but it precludes broker-side features that read payloads (e.g. Streams aggregations on the encrypted field).
+3. **Tiered storage** with a remote store that performs its own encryption.
+
+## Audit Logging
+
+Apache Kafka emits authorizer decisions to the `kafka.authorizer.logger` log4j logger. Setting this logger to `INFO` records every denied request; `DEBUG` records every allowed request as well. In regulated environments this log should be shipped to durable, append-only storage off-broker. There is no built-in tamper-evident audit trail.
+
+The request log (`kafka.request.logger`) provides finer detail on individual API calls and is useful for forensic investigation, but it is verbose and not enabled by default.
+
+## Secrets in Configuration
+
+Broker, client, and Connect properties files contain keystore passwords, SASL credentials, and similar secrets. Apache Kafka supports indirect references through `ConfigProvider` implementations (`FileConfigProvider`, `DirectoryConfigProvider`, or custom providers). Use them rather than embedding cleartext secrets in version-controlled configuration. For the file-based providers, set `allowed.paths` to the specific directories that hold those secrets so that a malicious or mistaken configuration cannot coerce the provider into reading arbitrary files elsewhere on the host. Sensitive dynamic broker configurations are encrypted at rest in the metadata log using `password.encoder.secret`; rotating that secret requires `password.encoder.old.secret` and a rolling restart.
+
+## Component-Specific Notes
+
+- **JMX.** Brokers expose operational metrics over JMX. JMX is an administrators/operators-only interface and must never be exposed to actual users. It is unauthenticated by default and should either be disabled, bound to localhost with an exporter alongside, or configured with `com.sun.management.jmxremote.authenticate=true` and TLS.
Review Comment:
All components can expose metrics via JMX, it's not limited to brokers
##########
docs/security/security-model-connect.md:
##########
@@ -0,0 +1,85 @@
+---
+title: Kafka Connect Security Model
+description: Apache Kafka Connect Security Model
+weight: 9
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+This page extends the [Apache Kafka security model](security-model) to Kafka Connect. A worker authenticates to the Kafka cluster over a configured `SASL_SSL`/`SSL` listener exactly like any other client, so everything the core model says about authentication, authorization, and transport encryption to the brokers applies unchanged. What follows covers only what Connect adds on top — chiefly its own control plane, the REST API, and the fact that it runs user-supplied code.
+
+## Things You Need To Know
+
+- **Connect inherits the broker's client security model.** Authentication to the brokers, broker-side authorization, and transport encryption are exactly as described in the [core security model](security-model). This page only describes what Connect layers on top.
+- **The REST API is unauthenticated by default.** Out of the box, anyone who can reach the REST port can create, reconfigure, stop, or delete any connector. Because connectors and plugins run arbitrary code, unrestricted REST access is effectively unrestricted code execution on the worker.
+- **Connect plugins run arbitrary code.** Connectors, converters, transformations, predicates, and REST extensions loaded from `plugin.path` execute in the worker JVM with its privileges. Install only plugins you trust.
+- **The REST API is a shared control plane with no per-connector isolation.** There is no notion of connector ownership: any caller allowed onto the API can act on every connector and read its configuration.
+- **A worker authenticates to Kafka as a single principal.** All connectors on a worker share that principal's identity and ACLs; Connect does not give each connector a distinct Kafka identity.
Review Comment:
This is overridable by connectors depending on `connector.client.config.override.policy`
##########
docs/security/security-model-connect.md:
##########
@@ -0,0 +1,85 @@
+---
+title: Kafka Connect Security Model
+description: Apache Kafka Connect Security Model
+weight: 9
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+This page extends the [Apache Kafka security model](security-model) to Kafka Connect. A worker authenticates to the Kafka cluster over a configured `SASL_SSL`/`SSL` listener exactly like any other client, so everything the core model says about authentication, authorization, and transport encryption to the brokers applies unchanged. What follows covers only what Connect adds on top — chiefly its own control plane, the REST API, and the fact that it runs user-supplied code.
+
+## Things You Need To Know
Review Comment:
Should we have not in scope/known issues section here too.
For examples include:
- Adding the File connectors to the classpath: this effectively grants read/write disk access
- FileConfigProvider and DirectoryConfigProvider don't handle symlinks in their path allowlist validation logic. While we should fix this issue, I don't consider it a security issue as it requires local disk access and the ability to create arbitrary symlinks on Connect workers.
- https://issues.apache.org/jira/browse/KAFKA-20450: Over the years we got a lot of reports for this one. We tidied the code recently but it's not in a release yet. Again not a security issue as it requires disk write access on Connect workers for exploitation.
- Using PropertyFileLoginModule, see https://github.com/apache/kafka/blob/trunk/connect/basic-auth-extension/src/main/java/org/apache/kafka/connect/rest/basic/auth/extension/PropertyFileLoginModule.java#L47-L48
##########
docs/security/security-model-mirrormaker.md:
##########
@@ -0,0 +1,35 @@
+---
+title: MirrorMaker 2 Security Model
+description: Apache Kafka MirrorMaker 2 Security Model
+weight: 11
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+This page extends the [Apache Kafka security model](security-model) to MirrorMaker 2. MirrorMaker 2 is built on Kafka Connect, so the [Connect security model](security-model-connect) applies in full; what follows is specific to replicating across clusters.
Review Comment:
Is there anything specific to MirrorMaker?
##########
docs/security/security-model-connect.md:
##########
@@ -0,0 +1,85 @@
+---
+title: Kafka Connect Security Model
+description: Apache Kafka Connect Security Model
+weight: 9
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+This page extends the [Apache Kafka security model](security-model) to Kafka Connect. A worker authenticates to the Kafka cluster over a configured `SASL_SSL`/`SSL` listener exactly like any other client, so everything the core model says about authentication, authorization, and transport encryption to the brokers applies unchanged. What follows covers only what Connect adds on top — chiefly its own control plane, the REST API, and the fact that it runs user-supplied code.
+
+## Things You Need To Know
+
+- **Connect inherits the broker's client security model.** Authentication to the brokers, broker-side authorization, and transport encryption are exactly as described in the [core security model](security-model). This page only describes what Connect layers on top.
+- **The REST API is unauthenticated by default.** Out of the box, anyone who can reach the REST port can create, reconfigure, stop, or delete any connector. Because connectors and plugins run arbitrary code, unrestricted REST access is effectively unrestricted code execution on the worker.
+- **Connect plugins run arbitrary code.** Connectors, converters, transformations, predicates, and REST extensions loaded from `plugin.path` execute in the worker JVM with its privileges. Install only plugins you trust.
+- **The REST API is a shared control plane with no per-connector isolation.** There is no notion of connector ownership: any caller allowed onto the API can act on every connector and read its configuration.
+- **A worker authenticates to Kafka as a single principal.** All connectors on a worker share that principal's identity and ACLs; Connect does not give each connector a distinct Kafka identity.
+- **Connect stores its state in Kafka topics.** Connector configurations (including any inlined secrets), source offsets, and status live in the `config.storage.topic`, `offset.storage.topic`, and `status.storage.topic`. Protect them with ACLs as you would any sensitive topic.
Review Comment:
This is only true when running in distributed mode.
##########
docs/security/security-model.md:
##########
@@ -0,0 +1,162 @@
+---
+title: Security Model
+description: Apache Kafka Security Model
+weight: 8
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+## Things You Need To Know
+
+- **Security is off by default.** A freshly-installed Apache Kafka cluster accepts unauthenticated `PLAINTEXT` connections on every listener and applies no authorization. This is appropriate only for closed test environments. Production deployments **must** explicitly configure authentication, authorization, and transport encryption before being exposed to any untrusted network.
+- **Apache Kafka assumes a trusted operator.** Anyone with shell access to a broker, controller, or the underlying disks can read every topic, forge any principal, and rewrite ACLs. The security model protects messages in transit and arbitrates client access — it does not defend brokers from their own administrators.
+- **Apache Kafka assumes a trusted broker fleet.** Brokers and KRaft controllers exchange records, replication state, and metadata over the inter-broker and controller listeners. Any host that can authenticate on those listeners is effectively part of the cluster's trust boundary.
+- **The data plane and the control plane have different exposure.** Producer/consumer traffic, the Admin API, and JMX each have distinct authentication and authorization stories. Operators must configure them independently — securing one does not secure the others.
+- **Apache Kafka does not encrypt data at rest.** Log segments, index files, and snapshots are written as plain bytes. At-rest confidentiality is the responsibility of the underlying filesystem, block device, or message-level encryption performed by producers.
+- **Reporting vulnerabilities.** Suspected security issues should be reported privately to `security@kafka.apache.org` per the [ASF security process](https://www.apache.org/security/). Do not file public JIRA tickets, GitHub issues, or mailing-list posts for unpatched vulnerabilities.
+
+## Listeners and the Network Boundary
+
+Apache Kafka brokers expose one or more **listeners**, each with an independent security configuration selected by `listener.security.protocol.map`. The four protocols are:
+
+| Protocol | Authentication | Encryption |
+|------------------|------------------------|------------|
+| `PLAINTEXT` | None | None |
+| `SSL` | Optional mTLS | TLS |
+| `SASL_PLAINTEXT` | SASL | None |
+| `SASL_SSL` | SASL (+ optional mTLS) | TLS |
+
+`inter.broker.listener.name` and `controller.listener.names` select which listeners carry replication and KRaft traffic respectively. A common pattern is to keep these on a dedicated internal listener (`SASL_SSL` or `SSL`) that is firewalled off from clients, so that a compromise of a client-facing listener cannot impersonate a broker.
+
+Operators should:
+
+1. Bind external listeners only to interfaces reachable by intended clients.
+2. Treat `advertised.listeners` as part of the security configuration — clients connect to whatever the broker advertises after the initial metadata fetch.
+3. Never expose the controller listener to client networks.
+
+## Authentication
+
+Apache Kafka supports two complementary authentication mechanisms; either may be used, and both can be combined on a `SASL_SSL` listener.
+
+### TLS Client Authentication (mTLS)
+
+When `ssl.client.auth` is `required` on a TLS listener, the client's X.509 certificate is verified against the broker's truststore. The authenticated principal is derived from the certificate's distinguished name via `ssl.principal.mapping.rules` (or a custom `KafkaPrincipalBuilder`).
+
+mTLS is the recommended mechanism for broker-to-broker and controller-to-broker traffic, because it requires no shared password material and rotates with the rest of the PKI.
+
+### SASL
+
+Apache Kafka ships with five SASL mechanisms, enabled per-listener via `sasl.enabled.mechanisms`:
+
+- **`GSSAPI`** — Kerberos. Recommended for environments that already operate a KDC; principals and credentials are managed externally.
+- **`SCRAM-SHA-256` / `SCRAM-SHA-512`** — Salted challenge/response with credentials stored in the cluster metadata. Credentials are managed with `kafka-configs.sh --alter --add-config 'SCRAM-SHA-512=...'`.
+- **`OAUTHBEARER`** — OAuth 2.0 bearer tokens, suitable for integration with an identity provider. The default unsecured implementation is for testing only; production deployments must configure a JWKS endpoint and validator.
+- **`PLAIN`** — Username/password sent in cleartext over the SASL channel. Acceptable only inside a `SASL_SSL` listener; never use it with `SASL_PLAINTEXT`.
+
+#### Delegation Tokens
+
+Once a client has authenticated via SASL or mTLS, it can request a short-lived **delegation token** that is then used as a `SCRAM-SHA-256` credential for subsequent connections. Delegation tokens are intended for distributed frameworks (Spark, Flink, Connect workers) that need to fan out to many tasks without distributing the original credential. Tokens inherit the requester's principal and ACLs, expire on a fixed schedule (`delegation.token.expiry.time.ms`), and can be invalidated by the owner.
+
+## Authorization
+
+Authentication establishes a `KafkaPrincipal`; authorization decides what that principal may do. Authorization is performed by the configured `authorizer.class.name`. Apache Kafka ships `org.apache.kafka.metadata.authorizer.StandardAuthorizer` for KRaft clusters.
+
+ACLs are tuples of `(principal, host, operation, resource pattern, permission)`. Resources are typed (`Topic`, `Group`, `Cluster`, `TransactionalId`, `DelegationToken`, `User`) and patterns may be `LITERAL` or `PREFIXED`.
+
+Defaults worth understanding:
+
+- If no authorizer is configured, **all authenticated principals have full access**. Configuring authentication without an authorizer provides identity but no authorization.
+- If an authorizer is configured but no ACLs match, access is **denied**. The exception is the principals listed in `super.users`, which bypass ACL checks entirely; treat that list as you would a root password.
+- `allow.everyone.if.no.acl.found=true` reverses the default-deny behaviour for resources that have no ACLs at all. It is a transitional aid for adding authorization to existing clusters and should not remain set in steady state.
+
+ACLs are managed with `kafka-acls.sh` or the AdminClient `createAcls`/`deleteAcls` APIs, which are themselves gated by ACLs on the `Cluster` resource.
+
+## Encryption in Transit
+
+TLS is configured per-listener via the standard `ssl.*` properties (`ssl.keystore.*`, `ssl.truststore.*`, `ssl.protocol`, `ssl.cipher.suites`, `ssl.enabled.protocols`). Recommendations:
+
+- Disable TLS versions below 1.2; prefer 1.3 where the JDK supports it.
+- Use distinct keystores for the inter-broker listener and any client-facing listener so that a leaked client-facing key cannot impersonate a broker.
+- Set `ssl.endpoint.identification.algorithm=https` on clients (the default since 2.0) so that the broker's certificate must match its hostname.
+- Rotate keystores using the dynamic broker configuration mechanism (`kafka-configs.sh --entity-type brokers --alter --add-config ...`) to avoid restarts.
+
+Kafka Connect, MirrorMaker 2, and Kafka Streams all consume the same `ssl.*` and `sasl.*` client configs — securing the broker is necessary but not sufficient.
+
+## Encryption at Rest
+
+Apache Kafka does not encrypt log segments, indexes, snapshots, or controller metadata on disk. Operators who require at-rest confidentiality have three options, in increasing order of cost:
+
+1. **Filesystem or block-device encryption** Transparent to Kafka; protects against disk theft and misdirected backups but not against anyone with broker login.
+2. **Message-level encryption.** Producers encrypt payloads (and optionally headers) before `send()`; consumers decrypt. Keys are managed by an external KMS. This is the only option that protects records from broker operators, but it precludes broker-side features that read payloads (e.g. Streams aggregations on the encrypted field).
+3. **Tiered storage** with a remote store that performs its own encryption.
+
+## Audit Logging
+
+Apache Kafka emits authorizer decisions to the `kafka.authorizer.logger` log4j logger. Setting this logger to `INFO` records every denied request; `DEBUG` records every allowed request as well. In regulated environments this log should be shipped to durable, append-only storage off-broker. There is no built-in tamper-evident audit trail.
+
+The request log (`kafka.request.logger`) provides finer detail on individual API calls and is useful for forensic investigation, but it is verbose and not enabled by default.
+
+## Secrets in Configuration
+
+Broker, client, and Connect properties files contain keystore passwords, SASL credentials, and similar secrets. Apache Kafka supports indirect references through `ConfigProvider` implementations (`FileConfigProvider`, `DirectoryConfigProvider`, or custom providers). Use them rather than embedding cleartext secrets in version-controlled configuration. For the file-based providers, set `allowed.paths` to the specific directories that hold those secrets so that a malicious or mistaken configuration cannot coerce the provider into reading arbitrary files elsewhere on the host. Sensitive dynamic broker configurations are encrypted at rest in the metadata log using `password.encoder.secret`; rotating that secret requires `password.encoder.old.secret` and a rolling restart.
+
+## Component-Specific Notes
+
+- **JMX.** Brokers expose operational metrics over JMX. JMX is an administrators/operators-only interface and must never be exposed to actual users. It is unauthenticated by default and should either be disabled, bound to localhost with an exporter alongside, or configured with `com.sun.management.jmxremote.authenticate=true` and TLS.
+
+The components built on top of the brokers and clients have their own security models, covered on separate pages:
+
+- [Kafka Connect](security-model-connect)
+- [Kafka Streams](security-model-streams)
+- [MirrorMaker 2](security-model-mirrormaker)
+
+## Development and Test Tooling
+
+Not everything shipped in the Apache Kafka source tree is part of the production attack surface. Some components exist only to develop, test, and release Kafka itself, and are explicitly out of scope for the security model — they are expected to run only in trusted development and CI environments, and issues in them are generally not treated as security vulnerabilities.
+
+- **Trogdor.** Trogdor is a test framework that injects faults and runs workloads by design, including arbitrary user-supplied commands. It is intended to run only in development environments; the project does not consider command execution through Trogdor a security issue.
+- **System tests and release tooling.** The `tests/` system-test harness and the scripts under `release/` are operator/developer tooling for building, testing, and publishing Kafka. They are not components of a running cluster.
+
+When assessing the attack surface of a deployed cluster, scope it to the brokers, KRaft controllers, the client and inter-broker/controller listeners, the Admin API, and JMX — not the development tooling above.
+
+## Classifying Reports
+
+To keep triage consistent, a reported issue is treated as exactly one of:
+
+- **A vulnerability** — it breaks one of the security properties above for an adversary that is in scope, such as an unauthenticated or unauthorized network client.
+- **A hardening suggestion** — no stated property is broken, but a safer default or an added guard would reduce the blast radius of misuse.
+- **Out of scope** — it requires capabilities the model already treats as trusted (operator-supplied configuration, keystores, ACL administration), an adversary the model does not cover (a trusted operator, peer broker, or controller), or an unsupported component (see Development and Test Tooling above).
+- **By design** — it concerns a property the model explicitly disclaims, such as at-rest confidentiality or isolation from a trusted operator.
+
+## Known Non-Findings
Review Comment:
Should we have this section in the Connect and Streams files as well?
##########
docs/security/security-model.md:
##########
@@ -0,0 +1,162 @@
+---
+title: Security Model
+description: Apache Kafka Security Model
+weight: 8
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+## Things You Need To Know
+
+- **Security is off by default.** A freshly-installed Apache Kafka cluster accepts unauthenticated `PLAINTEXT` connections on every listener and applies no authorization. This is appropriate only for closed test environments. Production deployments **must** explicitly configure authentication, authorization, and transport encryption before being exposed to any untrusted network.
+- **Apache Kafka assumes a trusted operator.** Anyone with shell access to a broker, controller, or the underlying disks can read every topic, forge any principal, and rewrite ACLs. The security model protects messages in transit and arbitrates client access — it does not defend brokers from their own administrators.
+- **Apache Kafka assumes a trusted broker fleet.** Brokers and KRaft controllers exchange records, replication state, and metadata over the inter-broker and controller listeners. Any host that can authenticate on those listeners is effectively part of the cluster's trust boundary.
+- **The data plane and the control plane have different exposure.** Producer/consumer traffic, the Admin API, and JMX each have distinct authentication and authorization stories. Operators must configure them independently — securing one does not secure the others.
+- **Apache Kafka does not encrypt data at rest.** Log segments, index files, and snapshots are written as plain bytes. At-rest confidentiality is the responsibility of the underlying filesystem, block device, or message-level encryption performed by producers.
+- **Reporting vulnerabilities.** Suspected security issues should be reported privately to `security@kafka.apache.org` per the [ASF security process](https://www.apache.org/security/). Do not file public JIRA tickets, GitHub issues, or mailing-list posts for unpatched vulnerabilities.
+
+## Listeners and the Network Boundary
+
+Apache Kafka brokers expose one or more **listeners**, each with an independent security configuration selected by `listener.security.protocol.map`. The four protocols are:
+
+| Protocol | Authentication | Encryption |
+|------------------|------------------------|------------|
+| `PLAINTEXT` | None | None |
+| `SSL` | Optional mTLS | TLS |
+| `SASL_PLAINTEXT` | SASL | None |
+| `SASL_SSL` | SASL (+ optional mTLS) | TLS |
+
+`inter.broker.listener.name` and `controller.listener.names` select which listeners carry replication and KRaft traffic respectively. A common pattern is to keep these on a dedicated internal listener (`SASL_SSL` or `SSL`) that is firewalled off from clients, so that a compromise of a client-facing listener cannot impersonate a broker.
+
+Operators should:
+
+1. Bind external listeners only to interfaces reachable by intended clients.
+2. Treat `advertised.listeners` as part of the security configuration — clients connect to whatever the broker advertises after the initial metadata fetch.
+3. Never expose the controller listener to client networks.
+
+## Authentication
+
+Apache Kafka supports two complementary authentication mechanisms; either may be used, and both can be combined on a `SASL_SSL` listener.
+
+### TLS Client Authentication (mTLS)
+
+When `ssl.client.auth` is `required` on a TLS listener, the client's X.509 certificate is verified against the broker's truststore. The authenticated principal is derived from the certificate's distinguished name via `ssl.principal.mapping.rules` (or a custom `KafkaPrincipalBuilder`).
+
+mTLS is the recommended mechanism for broker-to-broker and controller-to-broker traffic, because it requires no shared password material and rotates with the rest of the PKI.
+
+### SASL
+
+Apache Kafka ships with five SASL mechanisms, enabled per-listener via `sasl.enabled.mechanisms`:
+
+- **`GSSAPI`** — Kerberos. Recommended for environments that already operate a KDC; principals and credentials are managed externally.
+- **`SCRAM-SHA-256` / `SCRAM-SHA-512`** — Salted challenge/response with credentials stored in the cluster metadata. Credentials are managed with `kafka-configs.sh --alter --add-config 'SCRAM-SHA-512=...'`.
+- **`OAUTHBEARER`** — OAuth 2.0 bearer tokens, suitable for integration with an identity provider. The default unsecured implementation is for testing only; production deployments must configure a JWKS endpoint and validator.
+- **`PLAIN`** — Username/password sent in cleartext over the SASL channel. Acceptable only inside a `SASL_SSL` listener; never use it with `SASL_PLAINTEXT`.
+
+#### Delegation Tokens
+
+Once a client has authenticated via SASL or mTLS, it can request a short-lived **delegation token** that is then used as a `SCRAM-SHA-256` credential for subsequent connections. Delegation tokens are intended for distributed frameworks (Spark, Flink, Connect workers) that need to fan out to many tasks without distributing the original credential. Tokens inherit the requester's principal and ACLs, expire on a fixed schedule (`delegation.token.expiry.time.ms`), and can be invalidated by the owner.
+
+## Authorization
+
+Authentication establishes a `KafkaPrincipal`; authorization decides what that principal may do. Authorization is performed by the configured `authorizer.class.name`. Apache Kafka ships `org.apache.kafka.metadata.authorizer.StandardAuthorizer` for KRaft clusters.
+
+ACLs are tuples of `(principal, host, operation, resource pattern, permission)`. Resources are typed (`Topic`, `Group`, `Cluster`, `TransactionalId`, `DelegationToken`, `User`) and patterns may be `LITERAL` or `PREFIXED`.
+
+Defaults worth understanding:
+
+- If no authorizer is configured, **all authenticated principals have full access**. Configuring authentication without an authorizer provides identity but no authorization.
+- If an authorizer is configured but no ACLs match, access is **denied**. The exception is the principals listed in `super.users`, which bypass ACL checks entirely; treat that list as you would a root password.
+- `allow.everyone.if.no.acl.found=true` reverses the default-deny behaviour for resources that have no ACLs at all. It is a transitional aid for adding authorization to existing clusters and should not remain set in steady state.
+
+ACLs are managed with `kafka-acls.sh` or the AdminClient `createAcls`/`deleteAcls` APIs, which are themselves gated by ACLs on the `Cluster` resource.
+
+## Encryption in Transit
+
+TLS is configured per-listener via the standard `ssl.*` properties (`ssl.keystore.*`, `ssl.truststore.*`, `ssl.protocol`, `ssl.cipher.suites`, `ssl.enabled.protocols`). Recommendations:
+
+- Disable TLS versions below 1.2; prefer 1.3 where the JDK supports it.
+- Use distinct keystores for the inter-broker listener and any client-facing listener so that a leaked client-facing key cannot impersonate a broker.
+- Set `ssl.endpoint.identification.algorithm=https` on clients (the default since 2.0) so that the broker's certificate must match its hostname.
+- Rotate keystores using the dynamic broker configuration mechanism (`kafka-configs.sh --entity-type brokers --alter --add-config ...`) to avoid restarts.
+
+Kafka Connect, MirrorMaker 2, and Kafka Streams all consume the same `ssl.*` and `sasl.*` client configs — securing the broker is necessary but not sufficient.
+
+## Encryption at Rest
+
+Apache Kafka does not encrypt log segments, indexes, snapshots, or controller metadata on disk. Operators who require at-rest confidentiality have three options, in increasing order of cost:
+
+1. **Filesystem or block-device encryption** Transparent to Kafka; protects against disk theft and misdirected backups but not against anyone with broker login.
+2. **Message-level encryption.** Producers encrypt payloads (and optionally headers) before `send()`; consumers decrypt. Keys are managed by an external KMS. This is the only option that protects records from broker operators, but it precludes broker-side features that read payloads (e.g. Streams aggregations on the encrypted field).
+3. **Tiered storage** with a remote store that performs its own encryption.
+
+## Audit Logging
+
+Apache Kafka emits authorizer decisions to the `kafka.authorizer.logger` log4j logger. Setting this logger to `INFO` records every denied request; `DEBUG` records every allowed request as well. In regulated environments this log should be shipped to durable, append-only storage off-broker. There is no built-in tamper-evident audit trail.
+
+The request log (`kafka.request.logger`) provides finer detail on individual API calls and is useful for forensic investigation, but it is verbose and not enabled by default.
+
+## Secrets in Configuration
+
+Broker, client, and Connect properties files contain keystore passwords, SASL credentials, and similar secrets. Apache Kafka supports indirect references through `ConfigProvider` implementations (`FileConfigProvider`, `DirectoryConfigProvider`, or custom providers). Use them rather than embedding cleartext secrets in version-controlled configuration. For the file-based providers, set `allowed.paths` to the specific directories that hold those secrets so that a malicious or mistaken configuration cannot coerce the provider into reading arbitrary files elsewhere on the host. Sensitive dynamic broker configurations are encrypted at rest in the metadata log using `password.encoder.secret`; rotating that secret requires `password.encoder.old.secret` and a rolling restart.
+
+## Component-Specific Notes
+
+- **JMX.** Brokers expose operational metrics over JMX. JMX is an administrators/operators-only interface and must never be exposed to actual users. It is unauthenticated by default and should either be disabled, bound to localhost with an exporter alongside, or configured with `com.sun.management.jmxremote.authenticate=true` and TLS.
Review Comment:
I don't think we should put this section here. Maybe we'd need a section/paragraph about the JVM and how we assume its trusted (no bad JARs present in the classpath). Or maybe lift some of the environment content from https://github.com/potiuk/kafka/blob/5bbb3e86626d3141cfe5006ec2881c91fcac36e4/THREAT_MODEL.md#5-assumptions-about-the-environment
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] MINOR: A starting point for a formal security model [kafka]
Posted by "clolov (via GitHub)" <gi...@apache.org>.
clolov merged PR #22398:
URL: https://github.com/apache/kafka/pull/22398
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] MINOR: A starting point for a formal security model [kafka]
Posted by "clolov (via GitHub)" <gi...@apache.org>.
clolov commented on code in PR #22398:
URL: https://github.com/apache/kafka/pull/22398#discussion_r3324689748
##########
docs/security/security-model.md:
##########
@@ -0,0 +1,132 @@
+---
+title: Security Model
+description: Apache Kafka Security Model
+weight: 8
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+## Things You Need To Know
+
+- **Security is off by default.** A freshly-installed Apache Kafka cluster accepts unauthenticated `PLAINTEXT` connections on every listener and applies no authorization. This is appropriate only for closed test environments. Production deployments **must** explicitly configure authentication, authorization, and transport encryption before being exposed to any untrusted network.
+- **Apache Kafka assumes a trusted operator.** Anyone with shell access to a broker, controller, or the underlying disks can read every topic, forge any principal, and rewrite ACLs. The security model protects messages in transit and arbitrates client access — it does not defend brokers from their own administrators.
+- **Apache Kafka assumes a trusted broker fleet.** Brokers and KRaft controllers exchange records, replication state, and metadata over the inter-broker and controller listeners. Any host that can authenticate on those listeners is effectively part of the cluster's trust boundary.
+- **The data plane and the control plane have different exposure.** Producer/consumer traffic, the Admin API, the Kafka Connect REST API, and JMX each have distinct authentication and authorization stories. Operators must configure them independently — securing one does not secure the others.
+- **Apache Kafka does not encrypt data at rest.** Log segments, index files, and snapshots are written as plain bytes. At-rest confidentiality is the responsibility of the underlying filesystem, block device, or message-level encryption performed by producers.
+- **Reporting vulnerabilities.** Suspected security issues should be reported privately to `security@kafka.apache.org` per the [ASF security process](https://www.apache.org/security/). Do not file public JIRA tickets, GitHub issues, or mailing-list posts for unpatched vulnerabilities.
+
+## Listeners and the Network Boundary
+
+Apache Kafka brokers expose one or more **listeners**, each with an independent security configuration selected by `listener.security.protocol.map`. The four protocols are:
+
+| Protocol | Authentication | Encryption |
+|------------------|------------------------|------------|
+| `PLAINTEXT` | None | None |
+| `SSL` | Optional mTLS | TLS |
+| `SASL_PLAINTEXT` | SASL | None |
+| `SASL_SSL` | SASL (+ optional mTLS) | TLS |
+
+`inter.broker.listener.name` and `controller.listener.names` select which listeners carry replication and KRaft traffic respectively. A common pattern is to keep these on a dedicated internal listener (`SASL_SSL` or `SSL`) that is firewalled off from clients, so that a compromise of a client-facing listener cannot impersonate a broker.
+
+Operators should:
+
+1. Bind external listeners only to interfaces reachable by intended clients.
+2. Treat `advertised.listeners` as part of the security configuration — clients connect to whatever the broker advertises after the initial metadata fetch.
+3. Never expose the controller listener to client networks.
+
+## Authentication
+
+Apache Kafka supports two complementary authentication mechanisms; either may be used, and both can be combined on a `SASL_SSL` listener.
+
+### TLS Client Authentication (mTLS)
+
+When `ssl.client.auth` is `required` on a TLS listener, the client's X.509 certificate is verified against the broker's truststore. The authenticated principal is derived from the certificate's distinguished name via `ssl.principal.mapping.rules` (or a custom `KafkaPrincipalBuilder`).
+
+mTLS is the recommended mechanism for broker-to-broker and controller-to-broker traffic, because it requires no shared password material and rotates with the rest of the PKI.
+
+### SASL
+
+Apache Kafka ships with five SASL mechanisms, enabled per-listener via `sasl.enabled.mechanisms`:
+
+- **`GSSAPI`** — Kerberos. Recommended for environments that already operate a KDC; principals and credentials are managed externally.
+- **`SCRAM-SHA-256` / `SCRAM-SHA-512`** — Salted challenge/response with credentials stored in the cluster metadata. Credentials are managed with `kafka-configs.sh --alter --add-config 'SCRAM-SHA-512=...'`.
+- **`OAUTHBEARER`** — OAuth 2.0 bearer tokens, suitable for integration with an identity provider. The default unsecured implementation is for testing only; production deployments must configure a JWKS endpoint and validator.
+- **`PLAIN`** — Username/password sent in cleartext over the SASL channel. Acceptable only inside a `SASL_SSL` listener; never use it with `SASL_PLAINTEXT`.
+
+#### Delegation Tokens
+
+Once a client has authenticated via SASL or mTLS, it can request a short-lived **delegation token** that is then used as a `SCRAM-SHA-256` credential for subsequent connections. Delegation tokens are intended for distributed frameworks (Spark, Flink, Connect workers) that need to fan out to many tasks without distributing the original credential. Tokens inherit the requester's principal and ACLs, expire on a fixed schedule (`delegation.token.expiry.time.ms`), and can be invalidated by the owner.
+
+## Authorization
+
+Authentication establishes a `KafkaPrincipal`; authorization decides what that principal may do. Authorization is performed by the configured `authorizer.class.name`. Apache Kafka ships `org.apache.kafka.metadata.authorizer.StandardAuthorizer` for KRaft clusters.
+
+ACLs are tuples of `(principal, host, operation, resource pattern, permission)`. Resources are typed (`Topic`, `Group`, `Cluster`, `TransactionalId`, `DelegationToken`, `User`) and patterns may be `LITERAL` or `PREFIXED`.
+
+Defaults worth understanding:
+
+- If no authorizer is configured, **all authenticated principals have full access**. Configuring authentication without an authorizer provides identity but no authorization.
+- If an authorizer is configured but no ACLs match, access is **denied**. The exception is the principals listed in `super.users`, which bypass ACL checks entirely; treat that list as you would a root password.
+- `allow.everyone.if.no.acl.found=true` reverses the default-deny behaviour for resources that have no ACLs at all. It is a transitional aid for adding authorization to existing clusters and should not remain set in steady state.
+
+ACLs are managed with `kafka-acls.sh` or the AdminClient `createAcls`/`deleteAcls` APIs, which are themselves gated by ACLs on the `Cluster` resource.
+
+## Encryption in Transit
+
+TLS is configured per-listener via the standard `ssl.*` properties (`ssl.keystore.*`, `ssl.truststore.*`, `ssl.protocol`, `ssl.cipher.suites`, `ssl.enabled.protocols`). Recommendations:
+
+- Disable TLS versions below 1.2; prefer 1.3 where the JDK supports it.
+- Use distinct keystores for the inter-broker listener and any client-facing listener so that a leaked client-facing key cannot impersonate a broker.
+- Set `ssl.endpoint.identification.algorithm=https` on clients (the default since 2.0) so that the broker's certificate must match its hostname.
+- Rotate keystores using the dynamic broker configuration mechanism (`kafka-configs.sh --entity-type brokers --alter --add-config ...`) to avoid restarts.
+
+Kafka Connect, MirrorMaker 2, Kafka Streams, and the Schema Registry-style ecosystem tools all consume the same `ssl.*` and `sasl.*` client configs — securing the broker is necessary but not sufficient.
+
+## Encryption at Rest
+
+Apache Kafka does not encrypt log segments, indexes, snapshots, or controller metadata on disk. Operators who require at-rest confidentiality have three options, in increasing order of cost:
+
+1. **Filesystem or block-device encryption** Transparent to Kafka; protects against disk theft and misdirected backups but not against anyone with broker login.
+2. **Message-level encryption.** Producers encrypt payloads (and optionally headers) before `send()`; consumers decrypt. Keys are managed by an external KMS. This is the only option that protects records from broker operators, but it precludes broker-side features that read payloads (e.g. Streams aggregations on the encrypted field).
+3. **Tiered storage** with a remote store that performs its own encryption.
+
+## Audit Logging
+
+Apache Kafka emits authorizer decisions to the `kafka.authorizer.logger` log4j logger. Setting this logger to `INFO` records every denied request; `DEBUG` records every allowed request as well. In regulated environments this log should be shipped to durable, append-only storage off-broker. There is no built-in tamper-evident audit trail; integrate with the host's auditing pipeline.
+
+The request log (`kafka.request.logger`) provides finer detail on individual API calls and is useful for forensic investigation, but it is verbose and not enabled by default.
+
+## Secrets in Configuration
+
+Broker, client, and Connect properties files contain keystore passwords, SASL credentials, and similar secrets. Apache Kafka supports indirect references through `ConfigProvider` implementations (`FileConfigProvider`, `DirectoryConfigProvider`, or custom providers). Use them rather than embedding cleartext secrets in version-controlled configuration. Sensitive dynamic broker configurations are encrypted at rest in the metadata log using `password.encoder.secret`; rotating that secret requires `password.encoder.old.secret` and a rolling restart.
+
+## Component-Specific Notes
+
+- **Kafka Connect.** The REST API is unauthenticated by default; enable the built-in basic auth extension or front it with a reverse proxy. Connector configurations may contain credentials for external systems and should be stored via a `ConfigProvider`. Connect workers authenticate to the Kafka cluster as a single principal — partition that principal's ACLs by topic prefix per connector.
+- **Kafka Streams.** A Streams application authenticates as one principal that needs ACLs covering its source topics, internal repartition/changelog topics (typically `<application.id>-*`), and the consumer group `<application.id>`.
+- **MirrorMaker 2.** Replicates across security domains; configure `source.cluster.*` and `target.cluster.*` independently and never tunnel cleartext replication across an untrusted network.
+- **JMX.** Brokers expose operational metrics over JMX. JMX is unauthenticated by default and should either be disabled, bound to localhost with an exporter alongside, or configured with `com.sun.management.jmxremote.authenticate=true` and TLS.
Review Comment:
Do you mean for your suggestion to be added to the "or configured with `com.sun.management.jmxremote.authenticate=true` and TLS and never exposed to external customers"? Or do you mean it in general?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] MINOR: A starting point for a formal security model [kafka]
Posted by "clolov (via GitHub)" <gi...@apache.org>.
clolov commented on code in PR #22398:
URL: https://github.com/apache/kafka/pull/22398#discussion_r3324682385
##########
docs/security/security-model.md:
##########
@@ -0,0 +1,132 @@
+---
+title: Security Model
+description: Apache Kafka Security Model
+weight: 8
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+## Things You Need To Know
+
+- **Security is off by default.** A freshly-installed Apache Kafka cluster accepts unauthenticated `PLAINTEXT` connections on every listener and applies no authorization. This is appropriate only for closed test environments. Production deployments **must** explicitly configure authentication, authorization, and transport encryption before being exposed to any untrusted network.
+- **Apache Kafka assumes a trusted operator.** Anyone with shell access to a broker, controller, or the underlying disks can read every topic, forge any principal, and rewrite ACLs. The security model protects messages in transit and arbitrates client access — it does not defend brokers from their own administrators.
+- **Apache Kafka assumes a trusted broker fleet.** Brokers and KRaft controllers exchange records, replication state, and metadata over the inter-broker and controller listeners. Any host that can authenticate on those listeners is effectively part of the cluster's trust boundary.
+- **The data plane and the control plane have different exposure.** Producer/consumer traffic, the Admin API, the Kafka Connect REST API, and JMX each have distinct authentication and authorization stories. Operators must configure them independently — securing one does not secure the others.
+- **Apache Kafka does not encrypt data at rest.** Log segments, index files, and snapshots are written as plain bytes. At-rest confidentiality is the responsibility of the underlying filesystem, block device, or message-level encryption performed by producers.
+- **Reporting vulnerabilities.** Suspected security issues should be reported privately to `security@kafka.apache.org` per the [ASF security process](https://www.apache.org/security/). Do not file public JIRA tickets, GitHub issues, or mailing-list posts for unpatched vulnerabilities.
+
+## Listeners and the Network Boundary
+
+Apache Kafka brokers expose one or more **listeners**, each with an independent security configuration selected by `listener.security.protocol.map`. The four protocols are:
+
+| Protocol | Authentication | Encryption |
+|------------------|------------------------|------------|
+| `PLAINTEXT` | None | None |
+| `SSL` | Optional mTLS | TLS |
+| `SASL_PLAINTEXT` | SASL | None |
+| `SASL_SSL` | SASL (+ optional mTLS) | TLS |
+
+`inter.broker.listener.name` and `controller.listener.names` select which listeners carry replication and KRaft traffic respectively. A common pattern is to keep these on a dedicated internal listener (`SASL_SSL` or `SSL`) that is firewalled off from clients, so that a compromise of a client-facing listener cannot impersonate a broker.
+
+Operators should:
+
+1. Bind external listeners only to interfaces reachable by intended clients.
+2. Treat `advertised.listeners` as part of the security configuration — clients connect to whatever the broker advertises after the initial metadata fetch.
+3. Never expose the controller listener to client networks.
+
+## Authentication
+
+Apache Kafka supports two complementary authentication mechanisms; either may be used, and both can be combined on a `SASL_SSL` listener.
+
+### TLS Client Authentication (mTLS)
+
+When `ssl.client.auth` is `required` on a TLS listener, the client's X.509 certificate is verified against the broker's truststore. The authenticated principal is derived from the certificate's distinguished name via `ssl.principal.mapping.rules` (or a custom `KafkaPrincipalBuilder`).
+
+mTLS is the recommended mechanism for broker-to-broker and controller-to-broker traffic, because it requires no shared password material and rotates with the rest of the PKI.
+
+### SASL
+
+Apache Kafka ships with five SASL mechanisms, enabled per-listener via `sasl.enabled.mechanisms`:
+
+- **`GSSAPI`** — Kerberos. Recommended for environments that already operate a KDC; principals and credentials are managed externally.
+- **`SCRAM-SHA-256` / `SCRAM-SHA-512`** — Salted challenge/response with credentials stored in the cluster metadata. Credentials are managed with `kafka-configs.sh --alter --add-config 'SCRAM-SHA-512=...'`.
+- **`OAUTHBEARER`** — OAuth 2.0 bearer tokens, suitable for integration with an identity provider. The default unsecured implementation is for testing only; production deployments must configure a JWKS endpoint and validator.
+- **`PLAIN`** — Username/password sent in cleartext over the SASL channel. Acceptable only inside a `SASL_SSL` listener; never use it with `SASL_PLAINTEXT`.
+
+#### Delegation Tokens
+
+Once a client has authenticated via SASL or mTLS, it can request a short-lived **delegation token** that is then used as a `SCRAM-SHA-256` credential for subsequent connections. Delegation tokens are intended for distributed frameworks (Spark, Flink, Connect workers) that need to fan out to many tasks without distributing the original credential. Tokens inherit the requester's principal and ACLs, expire on a fixed schedule (`delegation.token.expiry.time.ms`), and can be invalidated by the owner.
+
+## Authorization
+
+Authentication establishes a `KafkaPrincipal`; authorization decides what that principal may do. Authorization is performed by the configured `authorizer.class.name`. Apache Kafka ships `org.apache.kafka.metadata.authorizer.StandardAuthorizer` for KRaft clusters.
+
+ACLs are tuples of `(principal, host, operation, resource pattern, permission)`. Resources are typed (`Topic`, `Group`, `Cluster`, `TransactionalId`, `DelegationToken`, `User`) and patterns may be `LITERAL` or `PREFIXED`.
+
+Defaults worth understanding:
+
+- If no authorizer is configured, **all authenticated principals have full access**. Configuring authentication without an authorizer provides identity but no authorization.
+- If an authorizer is configured but no ACLs match, access is **denied**. The exception is the principals listed in `super.users`, which bypass ACL checks entirely; treat that list as you would a root password.
+- `allow.everyone.if.no.acl.found=true` reverses the default-deny behaviour for resources that have no ACLs at all. It is a transitional aid for adding authorization to existing clusters and should not remain set in steady state.
+
+ACLs are managed with `kafka-acls.sh` or the AdminClient `createAcls`/`deleteAcls` APIs, which are themselves gated by ACLs on the `Cluster` resource.
+
+## Encryption in Transit
+
+TLS is configured per-listener via the standard `ssl.*` properties (`ssl.keystore.*`, `ssl.truststore.*`, `ssl.protocol`, `ssl.cipher.suites`, `ssl.enabled.protocols`). Recommendations:
+
+- Disable TLS versions below 1.2; prefer 1.3 where the JDK supports it.
+- Use distinct keystores for the inter-broker listener and any client-facing listener so that a leaked client-facing key cannot impersonate a broker.
+- Set `ssl.endpoint.identification.algorithm=https` on clients (the default since 2.0) so that the broker's certificate must match its hostname.
+- Rotate keystores using the dynamic broker configuration mechanism (`kafka-configs.sh --entity-type brokers --alter --add-config ...`) to avoid restarts.
+
+Kafka Connect, MirrorMaker 2, Kafka Streams, and the Schema Registry-style ecosystem tools all consume the same `ssl.*` and `sasl.*` client configs — securing the broker is necessary but not sufficient.
+
+## Encryption at Rest
+
+Apache Kafka does not encrypt log segments, indexes, snapshots, or controller metadata on disk. Operators who require at-rest confidentiality have three options, in increasing order of cost:
+
+1. **Filesystem or block-device encryption** Transparent to Kafka; protects against disk theft and misdirected backups but not against anyone with broker login.
+2. **Message-level encryption.** Producers encrypt payloads (and optionally headers) before `send()`; consumers decrypt. Keys are managed by an external KMS. This is the only option that protects records from broker operators, but it precludes broker-side features that read payloads (e.g. Streams aggregations on the encrypted field).
+3. **Tiered storage** with a remote store that performs its own encryption.
+
+## Audit Logging
+
+Apache Kafka emits authorizer decisions to the `kafka.authorizer.logger` log4j logger. Setting this logger to `INFO` records every denied request; `DEBUG` records every allowed request as well. In regulated environments this log should be shipped to durable, append-only storage off-broker. There is no built-in tamper-evident audit trail; integrate with the host's auditing pipeline.
+
+The request log (`kafka.request.logger`) provides finer detail on individual API calls and is useful for forensic investigation, but it is verbose and not enabled by default.
+
+## Secrets in Configuration
+
+Broker, client, and Connect properties files contain keystore passwords, SASL credentials, and similar secrets. Apache Kafka supports indirect references through `ConfigProvider` implementations (`FileConfigProvider`, `DirectoryConfigProvider`, or custom providers). Use them rather than embedding cleartext secrets in version-controlled configuration. Sensitive dynamic broker configurations are encrypted at rest in the metadata log using `password.encoder.secret`; rotating that secret requires `password.encoder.old.secret` and a rolling restart.
+
+## Component-Specific Notes
+
+- **Kafka Connect.** The REST API is unauthenticated by default; enable the built-in basic auth extension or front it with a reverse proxy. Connector configurations may contain credentials for external systems and should be stored via a `ConfigProvider`. Connect workers authenticate to the Kafka cluster as a single principal — partition that principal's ACLs by topic prefix per connector.
Review Comment:
Okay, thanks for details, I will expand this section
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] MINOR: A starting point for a formal security model [kafka]
Posted by "mimaison (via GitHub)" <gi...@apache.org>.
mimaison commented on code in PR #22398:
URL: https://github.com/apache/kafka/pull/22398#discussion_r3388022486
##########
docs/security/security-model.md:
##########
@@ -0,0 +1,162 @@
+---
+title: Security Model
+description: Apache Kafka Security Model
+weight: 8
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+## Things You Need To Know
+
+- **Security is off by default.** A freshly-installed Apache Kafka cluster accepts unauthenticated `PLAINTEXT` connections on every listener and applies no authorization. This is appropriate only for closed test environments. Production deployments **must** explicitly configure authentication, authorization, and transport encryption before being exposed to any untrusted network.
+- **Apache Kafka assumes a trusted operator.** Anyone with shell access to a broker, controller, or the underlying disks can read every topic, forge any principal, and rewrite ACLs. The security model protects messages in transit and arbitrates client access — it does not defend brokers from their own administrators.
+- **Apache Kafka assumes a trusted broker fleet.** Brokers and KRaft controllers exchange records, replication state, and metadata over the inter-broker and controller listeners. Any host that can authenticate on those listeners is effectively part of the cluster's trust boundary.
+- **The data plane and the control plane have different exposure.** Producer/consumer traffic, the Admin API, and JMX each have distinct authentication and authorization stories. Operators must configure them independently — securing one does not secure the others.
+- **Apache Kafka does not encrypt data at rest.** Log segments, index files, and snapshots are written as plain bytes. At-rest confidentiality is the responsibility of the underlying filesystem, block device, or message-level encryption performed by producers.
+- **Reporting vulnerabilities.** Suspected security issues should be reported privately to `security@kafka.apache.org` per the [ASF security process](https://www.apache.org/security/). Do not file public JIRA tickets, GitHub issues, or mailing-list posts for unpatched vulnerabilities.
+
+## Listeners and the Network Boundary
+
+Apache Kafka brokers expose one or more **listeners**, each with an independent security configuration selected by `listener.security.protocol.map`. The four protocols are:
+
+| Protocol | Authentication | Encryption |
+|------------------|------------------------|------------|
+| `PLAINTEXT` | None | None |
+| `SSL` | Optional mTLS | TLS |
+| `SASL_PLAINTEXT` | SASL | None |
+| `SASL_SSL` | SASL (+ optional mTLS) | TLS |
+
+`inter.broker.listener.name` and `controller.listener.names` select which listeners carry replication and KRaft traffic respectively. A common pattern is to keep these on a dedicated internal listener (`SASL_SSL` or `SSL`) that is firewalled off from clients, so that a compromise of a client-facing listener cannot impersonate a broker.
+
+Operators should:
+
+1. Bind external listeners only to interfaces reachable by intended clients.
+2. Treat `advertised.listeners` as part of the security configuration — clients connect to whatever the broker advertises after the initial metadata fetch.
+3. Never expose the controller listener to client networks.
+
+## Authentication
+
+Apache Kafka supports two complementary authentication mechanisms; either may be used, and both can be combined on a `SASL_SSL` listener.
+
+### TLS Client Authentication (mTLS)
+
+When `ssl.client.auth` is `required` on a TLS listener, the client's X.509 certificate is verified against the broker's truststore. The authenticated principal is derived from the certificate's distinguished name via `ssl.principal.mapping.rules` (or a custom `KafkaPrincipalBuilder`).
+
+mTLS is the recommended mechanism for broker-to-broker and controller-to-broker traffic, because it requires no shared password material and rotates with the rest of the PKI.
+
+### SASL
+
+Apache Kafka ships with five SASL mechanisms, enabled per-listener via `sasl.enabled.mechanisms`:
+
+- **`GSSAPI`** — Kerberos. Recommended for environments that already operate a KDC; principals and credentials are managed externally.
+- **`SCRAM-SHA-256` / `SCRAM-SHA-512`** — Salted challenge/response with credentials stored in the cluster metadata. Credentials are managed with `kafka-configs.sh --alter --add-config 'SCRAM-SHA-512=...'`.
+- **`OAUTHBEARER`** — OAuth 2.0 bearer tokens, suitable for integration with an identity provider. The default unsecured implementation is for testing only; production deployments must configure a JWKS endpoint and validator.
+- **`PLAIN`** — Username/password sent in cleartext over the SASL channel. Acceptable only inside a `SASL_SSL` listener; never use it with `SASL_PLAINTEXT`.
+
+#### Delegation Tokens
+
+Once a client has authenticated via SASL or mTLS, it can request a short-lived **delegation token** that is then used as a `SCRAM-SHA-256` credential for subsequent connections. Delegation tokens are intended for distributed frameworks (Spark, Flink, Connect workers) that need to fan out to many tasks without distributing the original credential. Tokens inherit the requester's principal and ACLs, expire on a fixed schedule (`delegation.token.expiry.time.ms`), and can be invalidated by the owner.
+
+## Authorization
+
+Authentication establishes a `KafkaPrincipal`; authorization decides what that principal may do. Authorization is performed by the configured `authorizer.class.name`. Apache Kafka ships `org.apache.kafka.metadata.authorizer.StandardAuthorizer` for KRaft clusters.
+
+ACLs are tuples of `(principal, host, operation, resource pattern, permission)`. Resources are typed (`Topic`, `Group`, `Cluster`, `TransactionalId`, `DelegationToken`, `User`) and patterns may be `LITERAL` or `PREFIXED`.
+
+Defaults worth understanding:
+
+- If no authorizer is configured, **all authenticated principals have full access**. Configuring authentication without an authorizer provides identity but no authorization.
+- If an authorizer is configured but no ACLs match, access is **denied**. The exception is the principals listed in `super.users`, which bypass ACL checks entirely; treat that list as you would a root password.
+- `allow.everyone.if.no.acl.found=true` reverses the default-deny behaviour for resources that have no ACLs at all. It is a transitional aid for adding authorization to existing clusters and should not remain set in steady state.
+
+ACLs are managed with `kafka-acls.sh` or the AdminClient `createAcls`/`deleteAcls` APIs, which are themselves gated by ACLs on the `Cluster` resource.
+
+## Encryption in Transit
+
+TLS is configured per-listener via the standard `ssl.*` properties (`ssl.keystore.*`, `ssl.truststore.*`, `ssl.protocol`, `ssl.cipher.suites`, `ssl.enabled.protocols`). Recommendations:
+
+- Disable TLS versions below 1.2; prefer 1.3 where the JDK supports it.
+- Use distinct keystores for the inter-broker listener and any client-facing listener so that a leaked client-facing key cannot impersonate a broker.
+- Set `ssl.endpoint.identification.algorithm=https` on clients (the default since 2.0) so that the broker's certificate must match its hostname.
+- Rotate keystores using the dynamic broker configuration mechanism (`kafka-configs.sh --entity-type brokers --alter --add-config ...`) to avoid restarts.
+
+Kafka Connect, MirrorMaker 2, and Kafka Streams all consume the same `ssl.*` and `sasl.*` client configs — securing the broker is necessary but not sufficient.
+
+## Encryption at Rest
+
+Apache Kafka does not encrypt log segments, indexes, snapshots, or controller metadata on disk. Operators who require at-rest confidentiality have three options, in increasing order of cost:
+
+1. **Filesystem or block-device encryption** Transparent to Kafka; protects against disk theft and misdirected backups but not against anyone with broker login.
+2. **Message-level encryption.** Producers encrypt payloads (and optionally headers) before `send()`; consumers decrypt. Keys are managed by an external KMS. This is the only option that protects records from broker operators, but it precludes broker-side features that read payloads (e.g. Streams aggregations on the encrypted field).
+3. **Tiered storage** with a remote store that performs its own encryption.
+
+## Audit Logging
+
+Apache Kafka emits authorizer decisions to the `kafka.authorizer.logger` log4j logger. Setting this logger to `INFO` records every denied request; `DEBUG` records every allowed request as well. In regulated environments this log should be shipped to durable, append-only storage off-broker. There is no built-in tamper-evident audit trail.
+
+The request log (`kafka.request.logger`) provides finer detail on individual API calls and is useful for forensic investigation, but it is verbose and not enabled by default.
+
+## Secrets in Configuration
+
+Broker, client, and Connect properties files contain keystore passwords, SASL credentials, and similar secrets. Apache Kafka supports indirect references through `ConfigProvider` implementations (`FileConfigProvider`, `DirectoryConfigProvider`, or custom providers). Use them rather than embedding cleartext secrets in version-controlled configuration. For the file-based providers, set `allowed.paths` to the specific directories that hold those secrets so that a malicious or mistaken configuration cannot coerce the provider into reading arbitrary files elsewhere on the host. Sensitive dynamic broker configurations are encrypted at rest in the metadata log using `password.encoder.secret`; rotating that secret requires `password.encoder.old.secret` and a rolling restart.
+
+## Component-Specific Notes
+
+- **JMX.** Brokers expose operational metrics over JMX. JMX is an administrators/operators-only interface and must never be exposed to actual users. It is unauthenticated by default and should either be disabled, bound to localhost with an exporter alongside, or configured with `com.sun.management.jmxremote.authenticate=true` and TLS.
+
+The components built on top of the brokers and clients have their own security models, covered on separate pages:
+
+- [Kafka Connect](security-model-connect)
+- [Kafka Streams](security-model-streams)
+- [MirrorMaker 2](security-model-mirrormaker)
+
+## Development and Test Tooling
+
+Not everything shipped in the Apache Kafka source tree is part of the production attack surface. Some components exist only to develop, test, and release Kafka itself, and are explicitly out of scope for the security model — they are expected to run only in trusted development and CI environments, and issues in them are generally not treated as security vulnerabilities.
+
+- **Trogdor.** Trogdor is a test framework that injects faults and runs workloads by design, including arbitrary user-supplied commands. It is intended to run only in development environments; the project does not consider command execution through Trogdor a security issue.
+- **System tests and release tooling.** The `tests/` system-test harness and the scripts under `release/` are operator/developer tooling for building, testing, and publishing Kafka. They are not components of a running cluster.
+
+When assessing the attack surface of a deployed cluster, scope it to the brokers, KRaft controllers, the client and inter-broker/controller listeners, the Admin API, and JMX — not the development tooling above.
+
+## Classifying Reports
+
+To keep triage consistent, a reported issue is treated as exactly one of:
+
+- **A vulnerability** — it breaks one of the security properties above for an adversary that is in scope, such as an unauthenticated or unauthorized network client.
+- **A hardening suggestion** — no stated property is broken, but a safer default or an added guard would reduce the blast radius of misuse.
+- **Out of scope** — it requires capabilities the model already treats as trusted (operator-supplied configuration, keystores, ACL administration), an adversary the model does not cover (a trusted operator, peer broker, or controller), or an unsupported component (see Development and Test Tooling above).
+- **By design** — it concerns a property the model explicitly disclaims, such as at-rest confidentiality or isolation from a trusted operator.
+
+## Known Non-Findings
Review Comment:
We could probably use some of the recent reports triaged as "not an issue" as examples as well
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] MINOR: A starting point for a formal security model [kafka]
Posted by "clolov (via GitHub)" <gi...@apache.org>.
clolov commented on PR #22398:
URL: https://github.com/apache/kafka/pull/22398#issuecomment-4681776392
> Now thinking in terms of format, do we need AGENTS.md and/or SECURITY.md files?
I was planning on using the ones from https://github.com/apache/kafka/pull/22431. I will include them in the subsequent commits which also address your latest comments 😊
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] MINOR: A starting point for a formal security model [kafka]
Posted by "mimaison (via GitHub)" <gi...@apache.org>.
mimaison commented on PR #22398:
URL: https://github.com/apache/kafka/pull/22398#issuecomment-4681693425
Now thinking in terms of format, do we need `AGENTS.md` and/or `SECURITY.md` files?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] MINOR: A starting point for a formal security model [kafka]
Posted by "mimaison (via GitHub)" <gi...@apache.org>.
mimaison commented on code in PR #22398:
URL: https://github.com/apache/kafka/pull/22398#discussion_r3396390527
##########
docs/security/security-model-connect.md:
##########
@@ -0,0 +1,93 @@
+---
+title: Kafka Connect Security Model
+description: Apache Kafka Connect Security Model
+weight: 9
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+This page extends the [Apache Kafka security model](security-model) to Kafka Connect. A worker authenticates to the Kafka cluster over a configured `SASL_SSL`/`SSL` listener exactly like any other client, so everything the core model says about authentication, authorization, and transport encryption to the brokers applies unchanged. What follows covers only what Connect adds on top — chiefly its own control plane, the REST API, and the fact that it runs user-supplied code.
+
+## Things You Need To Know
+
+- **Connect inherits the broker's client security model.** Authentication to the brokers, broker-side authorization, and transport encryption are exactly as described in the [core security model](security-model). This page only describes what Connect layers on top.
+- **The REST API is unauthenticated by default.** Out of the box, anyone who can reach the REST port can create, reconfigure, stop, or delete any connector. Because connectors and plugins run arbitrary code, unrestricted REST access is effectively unrestricted code execution on the worker.
+- **Connect plugins run arbitrary code.** Connectors, converters, transformations, predicates, and REST extensions loaded from `plugin.path` execute in the worker JVM with its privileges. Install only plugins you trust.
+- **The REST API is a shared control plane with no per-connector isolation.** There is no notion of connector ownership: any caller allowed onto the API can act on every connector and read its configuration.
+- **A worker authenticates to Kafka as a single principal.** By default all connectors on a worker share that principal's identity and ACLs; Connect does not give each connector a distinct Kafka identity. A connector can override the internal clients' configuration — including credentials — unless `connector.client.config.override.policy` restricts it (see Authorization below).
+- **In distributed mode, Connect stores its state in Kafka topics.** Connector configurations (including any inlined secrets), source offsets, and status live in the `config.storage.topic`, `offset.storage.topic`, and `status.storage.topic`; protect them with ACLs as you would any sensitive topic. In standalone mode, offsets are kept in a local file (`offset.storage.file.filename`) instead, so its protection is the host filesystem's responsibility.
+
+## The REST API and the Network Boundary
+
+The REST API is configured with the `listeners` property (for example `http://host:port` or `https://host:port`); if unset it defaults to `http` on port 8083. In distributed mode the REST API is *also* the inter-worker transport — a request received by a follower is forwarded to the leader — so it is simultaneously a user-facing management interface and an internal control channel. `rest.advertised.host.name`, `rest.advertised.port`, and `rest.advertised.listener` control the URL other workers use to reach a node.
+
+Operators should:
+
+1. Never expose the REST API to untrusted networks or users; bind it to a management network or front it with a reverse proxy.
+2. Use `admin.listeners` to separate the admin endpoints from the regular listeners, or set it to empty to disable them where they are not needed.
Review Comment:
If `admin.listeners` is not set, the `/admin` endpoints are attached to the default listeners.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] MINOR: A starting point for a formal security model [kafka]
Posted by "clolov (via GitHub)" <gi...@apache.org>.
clolov commented on code in PR #22398:
URL: https://github.com/apache/kafka/pull/22398#discussion_r3324678205
##########
docs/security/security-model.md:
##########
@@ -0,0 +1,132 @@
+---
+title: Security Model
+description: Apache Kafka Security Model
+weight: 8
+tags: ['kafka', 'docs', 'security']
+aliases:
+keywords:
+type: docs
+---
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+## Things You Need To Know
+
+- **Security is off by default.** A freshly-installed Apache Kafka cluster accepts unauthenticated `PLAINTEXT` connections on every listener and applies no authorization. This is appropriate only for closed test environments. Production deployments **must** explicitly configure authentication, authorization, and transport encryption before being exposed to any untrusted network.
+- **Apache Kafka assumes a trusted operator.** Anyone with shell access to a broker, controller, or the underlying disks can read every topic, forge any principal, and rewrite ACLs. The security model protects messages in transit and arbitrates client access — it does not defend brokers from their own administrators.
+- **Apache Kafka assumes a trusted broker fleet.** Brokers and KRaft controllers exchange records, replication state, and metadata over the inter-broker and controller listeners. Any host that can authenticate on those listeners is effectively part of the cluster's trust boundary.
+- **The data plane and the control plane have different exposure.** Producer/consumer traffic, the Admin API, the Kafka Connect REST API, and JMX each have distinct authentication and authorization stories. Operators must configure them independently — securing one does not secure the others.
+- **Apache Kafka does not encrypt data at rest.** Log segments, index files, and snapshots are written as plain bytes. At-rest confidentiality is the responsibility of the underlying filesystem, block device, or message-level encryption performed by producers.
+- **Reporting vulnerabilities.** Suspected security issues should be reported privately to `security@kafka.apache.org` per the [ASF security process](https://www.apache.org/security/). Do not file public JIRA tickets, GitHub issues, or mailing-list posts for unpatched vulnerabilities.
+
+## Listeners and the Network Boundary
+
+Apache Kafka brokers expose one or more **listeners**, each with an independent security configuration selected by `listener.security.protocol.map`. The four protocols are:
+
+| Protocol | Authentication | Encryption |
+|------------------|------------------------|------------|
+| `PLAINTEXT` | None | None |
+| `SSL` | Optional mTLS | TLS |
+| `SASL_PLAINTEXT` | SASL | None |
+| `SASL_SSL` | SASL (+ optional mTLS) | TLS |
+
+`inter.broker.listener.name` and `controller.listener.names` select which listeners carry replication and KRaft traffic respectively. A common pattern is to keep these on a dedicated internal listener (`SASL_SSL` or `SSL`) that is firewalled off from clients, so that a compromise of a client-facing listener cannot impersonate a broker.
+
+Operators should:
+
+1. Bind external listeners only to interfaces reachable by intended clients.
+2. Treat `advertised.listeners` as part of the security configuration — clients connect to whatever the broker advertises after the initial metadata fetch.
+3. Never expose the controller listener to client networks.
+
+## Authentication
+
+Apache Kafka supports two complementary authentication mechanisms; either may be used, and both can be combined on a `SASL_SSL` listener.
+
+### TLS Client Authentication (mTLS)
+
+When `ssl.client.auth` is `required` on a TLS listener, the client's X.509 certificate is verified against the broker's truststore. The authenticated principal is derived from the certificate's distinguished name via `ssl.principal.mapping.rules` (or a custom `KafkaPrincipalBuilder`).
+
+mTLS is the recommended mechanism for broker-to-broker and controller-to-broker traffic, because it requires no shared password material and rotates with the rest of the PKI.
+
+### SASL
+
+Apache Kafka ships with five SASL mechanisms, enabled per-listener via `sasl.enabled.mechanisms`:
+
+- **`GSSAPI`** — Kerberos. Recommended for environments that already operate a KDC; principals and credentials are managed externally.
+- **`SCRAM-SHA-256` / `SCRAM-SHA-512`** — Salted challenge/response with credentials stored in the cluster metadata. Credentials are managed with `kafka-configs.sh --alter --add-config 'SCRAM-SHA-512=...'`.
+- **`OAUTHBEARER`** — OAuth 2.0 bearer tokens, suitable for integration with an identity provider. The default unsecured implementation is for testing only; production deployments must configure a JWKS endpoint and validator.
+- **`PLAIN`** — Username/password sent in cleartext over the SASL channel. Acceptable only inside a `SASL_SSL` listener; never use it with `SASL_PLAINTEXT`.
+
+#### Delegation Tokens
+
+Once a client has authenticated via SASL or mTLS, it can request a short-lived **delegation token** that is then used as a `SCRAM-SHA-256` credential for subsequent connections. Delegation tokens are intended for distributed frameworks (Spark, Flink, Connect workers) that need to fan out to many tasks without distributing the original credential. Tokens inherit the requester's principal and ACLs, expire on a fixed schedule (`delegation.token.expiry.time.ms`), and can be invalidated by the owner.
+
+## Authorization
+
+Authentication establishes a `KafkaPrincipal`; authorization decides what that principal may do. Authorization is performed by the configured `authorizer.class.name`. Apache Kafka ships `org.apache.kafka.metadata.authorizer.StandardAuthorizer` for KRaft clusters.
+
+ACLs are tuples of `(principal, host, operation, resource pattern, permission)`. Resources are typed (`Topic`, `Group`, `Cluster`, `TransactionalId`, `DelegationToken`, `User`) and patterns may be `LITERAL` or `PREFIXED`.
+
+Defaults worth understanding:
+
+- If no authorizer is configured, **all authenticated principals have full access**. Configuring authentication without an authorizer provides identity but no authorization.
+- If an authorizer is configured but no ACLs match, access is **denied**. The exception is the principals listed in `super.users`, which bypass ACL checks entirely; treat that list as you would a root password.
+- `allow.everyone.if.no.acl.found=true` reverses the default-deny behaviour for resources that have no ACLs at all. It is a transitional aid for adding authorization to existing clusters and should not remain set in steady state.
+
+ACLs are managed with `kafka-acls.sh` or the AdminClient `createAcls`/`deleteAcls` APIs, which are themselves gated by ACLs on the `Cluster` resource.
+
+## Encryption in Transit
+
+TLS is configured per-listener via the standard `ssl.*` properties (`ssl.keystore.*`, `ssl.truststore.*`, `ssl.protocol`, `ssl.cipher.suites`, `ssl.enabled.protocols`). Recommendations:
+
+- Disable TLS versions below 1.2; prefer 1.3 where the JDK supports it.
+- Use distinct keystores for the inter-broker listener and any client-facing listener so that a leaked client-facing key cannot impersonate a broker.
+- Set `ssl.endpoint.identification.algorithm=https` on clients (the default since 2.0) so that the broker's certificate must match its hostname.
+- Rotate keystores using the dynamic broker configuration mechanism (`kafka-configs.sh --entity-type brokers --alter --add-config ...`) to avoid restarts.
+
+Kafka Connect, MirrorMaker 2, Kafka Streams, and the Schema Registry-style ecosystem tools all consume the same `ssl.*` and `sasl.*` client configs — securing the broker is necessary but not sufficient.
+
+## Encryption at Rest
+
+Apache Kafka does not encrypt log segments, indexes, snapshots, or controller metadata on disk. Operators who require at-rest confidentiality have three options, in increasing order of cost:
+
+1. **Filesystem or block-device encryption** Transparent to Kafka; protects against disk theft and misdirected backups but not against anyone with broker login.
+2. **Message-level encryption.** Producers encrypt payloads (and optionally headers) before `send()`; consumers decrypt. Keys are managed by an external KMS. This is the only option that protects records from broker operators, but it precludes broker-side features that read payloads (e.g. Streams aggregations on the encrypted field).
+3. **Tiered storage** with a remote store that performs its own encryption.
+
+## Audit Logging
+
+Apache Kafka emits authorizer decisions to the `kafka.authorizer.logger` log4j logger. Setting this logger to `INFO` records every denied request; `DEBUG` records every allowed request as well. In regulated environments this log should be shipped to durable, append-only storage off-broker. There is no built-in tamper-evident audit trail; integrate with the host's auditing pipeline.
+
+The request log (`kafka.request.logger`) provides finer detail on individual API calls and is useful for forensic investigation, but it is verbose and not enabled by default.
+
+## Secrets in Configuration
+
+Broker, client, and Connect properties files contain keystore passwords, SASL credentials, and similar secrets. Apache Kafka supports indirect references through `ConfigProvider` implementations (`FileConfigProvider`, `DirectoryConfigProvider`, or custom providers). Use them rather than embedding cleartext secrets in version-controlled configuration. Sensitive dynamic broker configurations are encrypted at rest in the metadata log using `password.encoder.secret`; rotating that secret requires `password.encoder.old.secret` and a rolling restart.
Review Comment:
Fair callout, will include!
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: jira-unsubscribe@kafka.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org