Document the topics, the consumer account and the credentials store
The README described the cluster as it was before events existed: no declared topics, no consumer, and no way for another namespace to reach a password Strimzi keeps here. The events themselves are specified by their producer, not here — this repo owns the cluster, not the contract. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -41,16 +41,70 @@ kafka-kafka-bootstrap.kafka.svc.cluster.local:9093
|
||||
| `kafka-admin` | `kafka-admin` | Super user — unrestricted access |
|
||||
| `kafka-client` | `kafka-client` | Application user — Read/Write all topics and groups |
|
||||
| `classic-models-api` | `classic-models-api` | Producer for `classic-models.*` — **Write and Describe only**, no Read |
|
||||
| `classic-models-agent-approvisionnement` | same name | Consumer of `classic-models.catalog` and group prefix `approvisionnement-` — **Read and Describe only**, no Write |
|
||||
|
||||
`classic-models-api` publishes domain events and consumes nothing, so it is
|
||||
write-only and prefix-scoped. A producer that can also read every topic is a
|
||||
producer that exfiltrates every other domain's events if it is ever
|
||||
compromised.
|
||||
Each application account is scoped to what it actually does. The producer
|
||||
publishes domain events and consumes nothing, so it is write-only: one that
|
||||
could also read every topic exfiltrates every other domain's events if it is
|
||||
ever compromised. The consumer is the mirror — it cannot see sales or payments,
|
||||
and it cannot write, so a compromised workflow can raise no event that another
|
||||
agent would then act on.
|
||||
|
||||
Duplicate one of these per application. `kafka-client` is the wide-open
|
||||
template, useful for a smoke test and for nothing that runs unattended.
|
||||
|
||||
Strimzi stores credentials in Kubernetes secrets. Each secret contains two keys:
|
||||
- `password` — the SCRAM password
|
||||
- `sasl.jaas.config` — the ready-to-use JAAS config string
|
||||
|
||||
### Topics
|
||||
|
||||
Declared in `kafka-topics.yaml`, never auto-created — an application account has
|
||||
no `Create` ACL, so a producer would simply be denied, and an auto-created topic
|
||||
takes broker defaults nobody chose.
|
||||
|
||||
| Topic | Partitions | Replicas | Retention |
|
||||
|---|---|---|---|
|
||||
| `classic-models.catalog` | 3 | 1 | 7 days |
|
||||
| `classic-models.sales` | 3 | 1 | 7 days |
|
||||
| `classic-models.payments` | 3 | 1 | 7 days |
|
||||
|
||||
Partition count is the ceiling on consumer parallelism and **cannot be lowered
|
||||
later**, so it is set for the traffic expected rather than the traffic today.
|
||||
|
||||
The events these carry are specified by their producer, in
|
||||
`classic-models-api/docs/DOMAIN_EVENTS.md`. This repo owns the cluster, not the
|
||||
contract.
|
||||
|
||||
### Getting credentials into another namespace
|
||||
|
||||
A Secret cannot be mounted across namespaces, and Strimzi writes a KafkaUser's
|
||||
password into **this** one. `credentials-access.yaml` therefore declares a
|
||||
`ClusterSecretStore` named `kafka-credentials` (External Secrets, `kubernetes`
|
||||
provider) backed by a ServiceAccount that can read Secrets here and nowhere
|
||||
else. An application namespace then pulls its own password and the cluster CA
|
||||
with an `ExternalSecret`:
|
||||
|
||||
```yaml
|
||||
secretStoreRef:
|
||||
kind: ClusterSecretStore
|
||||
name: kafka-credentials
|
||||
data:
|
||||
- secretKey: password
|
||||
remoteRef: {key: <kafkauser-name>, property: password}
|
||||
- secretKey: ca.crt
|
||||
remoteRef: {key: kafka-cluster-ca-cert, property: ca.crt}
|
||||
```
|
||||
|
||||
The password stays generated and rotatable by Strimzi; the copy follows. The
|
||||
alternative — copying it by hand — drifts the first time the user is
|
||||
regenerated.
|
||||
|
||||
**The trade, stated:** any namespace allowed to create an `ExternalSecret`
|
||||
against this store can pull **any** Kafka account's credentials. Acceptable with
|
||||
one operator; on a shared cluster, narrow the Role with `resourceNames` and run
|
||||
one store per application.
|
||||
|
||||
### TLS
|
||||
|
||||
Strimzi generates and manages its own internal CA. The cluster CA certificate is stored in:
|
||||
@@ -125,6 +179,8 @@ The target performs the following steps:
|
||||
3. Waits for the Strimzi CRDs to be fully established
|
||||
4. Applies `kafka.yaml` (KafkaNodePool + Kafka CRs) and waits for `Ready`
|
||||
5. Applies `kafka-users.yaml` (KafkaUser CRs) and waits for `Ready`
|
||||
6. Applies `kafka-topics.yaml` (the declared topics) and `credentials-access.yaml`
|
||||
(the cross-namespace credentials store)
|
||||
|
||||
Expected duration: **4–6 minutes** on a single-node k3s cluster.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user