Cluster-level authorizer selection. When None, the broker uses the default AllowAll authorizer and makes no ACL checks. When Some, the operator renders the [authorization] TOML section, so the broker builds the matching Arc<dyn Authorizer>. That is SimpleAclAuthorizer for type: simple, and OpaAuthorizer for type: opa. With simple or opa selected, the operator's inter-broker principal MUST appear in super_users. There is no implicit ANONYMOUS allow, and operators must opt in explicitly.
authorization.allowOnError
boolean
no
authorization.expireAfterMs
integer
no
authorization.initialCacheCapacity
integer
no
authorization.maximumCacheSize
integer
no
authorization.superUsers
array
no
authorization.type
string
yes
authorization.url
string
no
brokerTuning
object
no
Validated broker operational policy rendered into [runtime].
Per-cluster CA that signs KafkaUser TLS certs. When absent, the operator uses a fully-defaulted CertificateAuthority.
clientsCa.generateCertificateAuthority
boolean
no
true
When true, which is the default, the operator generates and renews this CA. When false, the cluster admin must create the CA Secret pair first, and the operator refuses to overwrite them. The admin renews a BYO CA. The CronJob skips a BYO CA and emits an Event when the CA comes near its expiry.
clientsCa.renewalDays
integer
no
30
Window in days before notAfter in which the renewal CronJob reissues the leaf certs. Default 30.
clientsCa.validityDays
integer
no
365
Cert validity in days. Default 365.
clusterCa
object
no
Per-cluster CA for inter-broker mTLS and broker certs. When absent, the operator uses a fully-defaulted CertificateAuthority, which it generates itself with 365/30 days.
clusterCa.generateCertificateAuthority
boolean
no
true
When true, which is the default, the operator generates and renews this CA. When false, the cluster admin must create the CA Secret pair first, and the operator refuses to overwrite them. The admin renews a BYO CA. The CronJob skips a BYO CA and emits an Event when the CA comes near its expiry.
clusterCa.renewalDays
integer
no
30
Window in days before notAfter in which the renewal CronJob reissues the leaf certs. Default 30.
clusterCa.validityDays
integer
no
365
Cert validity in days. Default 365.
config
object
no
Opaque broker properties, in server.properties-style key and value pairs. The operator passes them through to the broker's [server_properties] TOML table, and the broker treats them as inert today. Changes propagate through the config hash.
delegationToken
object
no
Delegation-token master HMAC key source. When None, the broker rejects all KIP-48 delegation-token RPCs with err 61 DELEGATION_TOKEN_AUTH_DISABLED. When Some, the operator injects CRABKA_DELEGATION_TOKEN_SECRET_KEY into each broker pod through a valueFrom.secretKeyRef. The key is then part of the rendered StatefulSet, so the SSA reconcile does not race with out-of-band kubectl set env patches.
delegationToken.secretKeyRef
object
yes
Reference to a Kubernetes Secret in the same namespace as the Kafka CR. Its data.<key> value is the broker's master HMAC key for KIP-48 delegation tokens.
delegationToken.secretKeyRef.key
string
no
Key within the Secret's data. Defaults to secret-key.
delegationToken.secretKeyRef.name
string
yes
Secret name in the same namespace as the Kafka CR.
gresRegistry
object
no
Shared creation and reader policy for the Gres tenant registry topic.
gresRegistry.fetchMaxWait
string
no
Maximum time a registry fetch waits for data.
gresRegistry.fetchPartitionMax
string
no
Maximum bytes fetched from the registry partition.
gresRegistry.producerDnsTimeout
string
no
DNS lookup deadline for the registry producer.
gresRegistry.readerAdminDnsTimeout
string
no
DNS lookup deadline for registry reader and admin paths.
gresRegistry.readerFetchMin
string
no
Minimum response size for registry reader fetches.
gresRegistry.readerRetryBackoff
string
no
Registry reader retry delay.
gresRegistry.replicationFactor
integer
no
Registry topic replication factor.
gresRegistry.topicCreateTimeout
string
no
Kafka topic creation timeout.
interBrokerKerberos
object
no
Inter-broker Kerberos initiate config. It is required when interBrokerListenerName resolves to a type: gssapi listener. It supplies the shared client principal and the KDC. The keytab comes from that listener's keytabSecretRef.
interBrokerKerberos.clientPrincipal
string
yes
Principal that every broker authenticates as when it dials peers, for example kafka@EXAMPLE.COM. It must exist in the shared keytab.
interBrokerKerberos.kdcUrl
string
yes
KDC endpoint, for example tcp://kdc:88.
interBrokerKerberos.serviceName
string
no
Target SPN primary. Defaults to kafka.
interBrokerListenerName
string
no
Name of the listener for inter-broker traffic. When None, the operator picks the first internal listener. When listeners is empty, the operator picks the synthesized default "PLAIN".
kafkaVersion
string
yes
Crabka version label. The operator propagates it to all pool pods through the app.kubernetes.io/version label.
krb5ConfSecretRef
object
no
Optional process-wide krb5.conf. The operator mounts it into the broker pods and points KRB5_CONFIG at it. It serves both the accept path and the initiate path.
krb5ConfSecretRef.key
string
yes
Key within the Secret whose value is the krb5.conf contents.
krb5ConfSecretRef.secretName
string
yes
Name of the Secret holding the krb5.conf.
listeners
array
no
Named listeners. An empty or absent list synthesizes one internal PLAIN listener on port 9092.
logging
object
no
Broker log configuration. When None, the brokers use their built-in default RUST_LOG filter. When Some, the operator composes an inline tracing env-filter string, or reads an external one. The operator then renders it into the broker ConfigMap under the rust.log key, wires it into the RUST_LOG env of each broker pod, and rolls the cluster on a change through the config hash.
logging.loggers
object
no
Inline loggers, from tracing target to level. The key root is case-insensitive and sets the global default level as a bare env-filter directive. Any other key is a tracing target, that is, a Rust module path such as crabka_broker. The levels are trace|debug|info|warn|error|off, and they are case-insensitive. fatal is accepted as an alias for error.
logging.type
string
no
inline
logging.valueFrom
object
no
External logging source. This field is required when type: external. The operator uses the value of the referenced ConfigMap key verbatim as the broker's RUST_LOG filter.
logging.valueFrom.configMapKeyRef
object
yes
logging.valueFrom.configMapKeyRef.key
string
yes
logging.valueFrom.configMapKeyRef.name
string
yes
metadataVersion
string
no
KRaft metadata version, the runtime analog of inter.broker.protocol.version. When unset, it tracks the major.minor of kafkaVersion. When set, it pins the metadata version for the safe two-step upgrade. The operator validates it against kafkaVersion and the finalized status.metadataVersion. An invalid value surfaces KafkaVersionValid=False and blocks the roll.
metricsConfig
object
no
Prometheus scrape configuration. When None, the brokers do not bind /metrics, and the operator renders no PodMonitor and no ServiceMonitor. When Some, the broker StatefulSet gains a metrics container port on TCP 9404, and the operator SSA-applies the resources that pod_monitor and service_monitor request.
metricsConfig.podMonitor
object
no
metricsConfig.podMonitor.interval
string
no
metricsConfig.podMonitor.labels
object
no
metricsConfig.podMonitor.scrapeTimeout
string
no
metricsConfig.serviceMonitor
object
no
metricsConfig.serviceMonitor.interval
string
no
metricsConfig.serviceMonitor.labels
object
no
metricsConfig.serviceMonitor.scrapeTimeout
string
no
metricsConfig.type
string
no
prometheus
networkPolicy
object
no
Opt-in NetworkPolicy generation. When None, the operator generates no NetworkPolicy. When Some, even {}, the operator renders a cluster-level NetworkPolicy that gates ingress to the broker and controller pods.
tieredStorage
object
no
KIP-405: cluster-wide tiered storage. When Some, every broker pod boots with the local-tier RSM enabled, with an emptyDir mounted at /var/lib/crabka/remote, which is the broker's remote_log_storage_dir, and with [remote_storage] rendered in the broker TOML. The per-topic enablement does not change. It stays KafkaTopic.spec.config["remote.storage.enable"] = "true". With the emptyDir default and InmemoryRemoteLogMetadataManager as the only RLMM, tier data does not survive pod restarts. PVC support pairs with the production RLMM.
tieredStorage.gcs
object
no
GCS-backend tuning. It is required when kind == Gcs, and it must be absent in any other case. The struct has the same shape as crabka_remote_storage::GcsConfig. The operator renders the non-credential fields verbatim into the broker TOML's [remote_storage.gcs] block. S3 uses env-var credentials, but GCS does not. The operator mounts an explicit service-account JSON key as a FILE on the broker pod and gives it to the broker as service_account_path in the TOML. Unset credentials select keyless Workload Identity or ADC.
tieredStorage.gcs.allowHttp
boolean
no
Allow plaintext HTTP. It is off by default. Turn it on for GCS emulators that run without TLS. Real GCS never needs it.
tieredStorage.gcs.bucket
string
yes
GCS bucket name. Required.
tieredStorage.gcs.credentials
object
no
Optional explicit service-account credentials. When None, the broker uses Workload Identity or ADC, which is the keyless GKE path.
tieredStorage.gcs.credentials.serviceAccountKey
object
yes
Reference to the Secret holding the service-account JSON key.
Secret name in the same namespace as the Kafka CR.
tieredStorage.gcs.endpoint
string
no
Optional custom GCS API base URL, for example for emulators and fakes. When None, the broker uses the standard Google Cloud Storage endpoint.
tieredStorage.gcs.multipartChunkSize
integer
no
Override the per-part size for multipart uploads in bytes. When unset, the broker uses crabka_remote_storage::DEFAULT_MULTIPART_CHUNK_SIZE, which is 16 MiB.
tieredStorage.gcs.multipartThreshold
integer
no
Override the single-PUT and multipart cutoff in bytes. When unset, the broker uses crabka_remote_storage::DEFAULT_MULTIPART_THRESHOLD, which is 100 MiB. Lower it in tests to exercise the multipart path on small fixtures.
tieredStorage.gcs.prefix
string
no
Optional key prefix inside the bucket. It lets more than one Crabka cluster share a bucket without a collision.
tieredStorage.metadataManager
object
no
KIP-405: pick the RemoteLogMetadataManager that the broker pods run. When the field is absent, or when it is type: Topic, the broker activates the durable crabka_remote_storage_topic::TopicBasedRemoteLogMetadataManager against the internal __remote_log_metadata topic. Tier-segment metadata then survives pod restarts and is consistent across the brokers in the cluster. Only an explicit type: InMemory selects the in-memory fixture, which is for test and dev only.
tieredStorage.metadataManager.topic
object
no
Topic-backed tuning. It is optional when kind == Topic, and the broker fills the defaults for the bootstrap and topic parameters. It must be absent in any other case.
tieredStorage.metadataManager.topic.bootstrap
string
yes
host:port that the broker pod dials to reach its own listener, so that it can publish and consume __remote_log_metadata. This is usually the pod's loopback inter-broker listener, for example 127.0.0.1:9094.
Timeout for provisioning each internal metadata topic.
tieredStorage.metadataManager.type
string
yes
Implementation selector.
tieredStorage.persistence
object
no
KIP-405: durable storage for the local-tier directory. It is valid only with type=Local. When it is absent, which is the default, the operator renders an emptyDir for tier-storage. When Some, the operator renders a volumeClaimTemplate of the configured size and class, so tier data survives pod restarts. Together with the topic-backed RLMM, this closes the "tier data is lost on pod restart" caveat.
tieredStorage.persistence.class
string
no
Storage class name. None means the cluster default.
tieredStorage.persistence.deleteClaim
boolean
no
false
true gives persistentVolumeClaimRetentionPolicy.whenDeleted: Delete. It must match the parent KafkaNodePool.spec.storage.deleteClaim when both PVCs are present, because K8s StatefulSets have one set-wide retention policy and no per-template override. The operator validates this at reconcile time, and a mismatch surfaces as TieredStorageInvalid.
tieredStorage.persistence.size
string
yes
K8s Quantity, for example "50Gi" or "500Mi". It must be non-empty. The Kubernetes API server validates the resource-quantity form at SSA time.
tieredStorage.s3
object
no
S3-backend tuning. It is required when kind == S3, and it must be absent in any other case. The struct has the same shape as crabka_remote_storage::S3Config. The operator renders the non-credential fields verbatim into the broker TOML's [remote_storage.s3] block. The credentials come from Kubernetes Secrets, and the operator injects them as the broker-pod env vars AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.
tieredStorage.s3.allowHttp
boolean
no
Allow plaintext HTTP. It is off by default. Turn it on for a MinIO that runs without TLS. AWS S3 never needs it.
tieredStorage.s3.bucket
string
yes
S3 bucket name. Required.
tieredStorage.s3.credentials
object
no
Optional explicit credentials. When None, the broker falls back to the AWS credential chain, such as IRSA on EKS or an instance profile on EC2.
tieredStorage.s3.credentials.accessKeyId
object
yes
Reference to the Secret holding the AWS_ACCESS_KEY_ID value.
tieredStorage.s3.credentials.accessKeyId.key
string
no
Key within the Secret's data. Defaults to secret-key.
tieredStorage.s3.credentials.accessKeyId.name
string
yes
Secret name in the same namespace as the Kafka CR.
tieredStorage.s3.credentials.secretAccessKey
object
yes
Reference to the Secret holding the AWS_SECRET_ACCESS_KEY value.
tieredStorage.s3.credentials.secretAccessKey.key
string
no
Key within the Secret's data. Defaults to secret-key.
tieredStorage.s3.credentials.secretAccessKey.name
string
yes
Secret name in the same namespace as the Kafka CR.
tieredStorage.s3.endpoint
string
no
Optional custom endpoint URL, for example http://minio:9000 for MinIO, or https://<account>.r2.cloudflarestorage.com for Cloudflare R2. When None, the broker uses the AWS S3 endpoint for the configured region.
tieredStorage.s3.multipartChunkSize
integer
no
Override the per-part size for multipart uploads in bytes. When unset, the broker uses crabka_remote_storage::DEFAULT_MULTIPART_CHUNK_SIZE, which is 16 MiB.
tieredStorage.s3.multipartThreshold
integer
no
Override the single-PUT and multipart cutoff in bytes. When unset, the broker uses crabka_remote_storage::DEFAULT_MULTIPART_THRESHOLD, which is 100 MiB. Lower it in tests to exercise the multipart path on small fixtures.
tieredStorage.s3.prefix
string
no
Optional key prefix inside the bucket. It lets more than one Crabka cluster share a bucket without a collision.
tieredStorage.s3.region
string
yes
AWS region. It is required even for the non-AWS endpoints MinIO and R2, because the AmazonS3Builder of object_store rejects an empty region.
tieredStorage.type
string
yes
Backend kind selector.
tracing
object
no
Distributed-tracing wiring for the broker pods. When Some, the operator renders the matching CRABKA_OTLP_* env vars onto every broker pod. The broker's telemetry pipeline reads them with TelemetryConfig::from_env and installs the OTLP tracer at startup. When None, the operator emits no OTLP env vars, and the broker leaves tracing off. That is the default.
tracing.otlp
object
no
OTLP-backend tuning. Required when kind == Otlp.
tracing.otlp.endpoint
string
yes
Required. OTLP collector endpoint in the form scheme://host:port. The operator renders it as CRABKA_OTLP_ENDPOINT. A set field also sets CRABKA_OTLP_ENABLED=true.
tracing.otlp.protocol
string
no
OTLP wire protocol selector. It has the same shape as the broker's internal OtlpProtocol enum and the OTEL_EXPORTER_OTLP_PROTOCOL spec values.
tracing.otlp.sampleRatio
number
no
Optional sampling ratio in [0.0, 1.0]. The operator renders it as CRABKA_OTLP_SAMPLE_RATIO. An unset field leaves the binary's own default of 1.0, which samples every trace.
tracing.otlp.serviceName
string
no
Optional service.name resource attribute. The operator renders it as OTEL_SERVICE_NAME. An unset field leaves the binary's own name, which is "crabka-broker" for Kafka and "crabka-gres" for Gres.
tracing.otlp.timeout
string
no
Optional export timeout. The operator renders it as CRABKA_OTLP_TIMEOUT. An unset field leaves the binary's own default of 10s.
tracing.type
string
yes
Tracing backend selector.
Status
Field
Type
Required
Default
Description
clientsCa
object
no
Status surface for one CA. The reconciler fills it in from the parsed CA cert and the CRD spec.
clientsCa.certGeneration
integer
no
0
Monotonic generation of the active signing cert. It increments on a same-key renewal and on a key promotion.
clientsCa.generated
boolean
yes
true when the operator generated this CA, that is, when generateCertificateAuthority == true. false for a BYO CA.
clientsCa.keyGeneration
integer
no
0
Monotonic generation of the active signing key. It increments only on a key replacement.
clientsCa.notAfter
string
yes
RFC3339 notAfter of the current CA cert, which is the signing cert.
clientsCa.rotationPhase
string
no
Staged key-replacement phase. One of idle, key-replace-trust, and key-replace-promote.
clientsCa.trustAnchors
integer
no
Number of CA certs in the trust bundle now.
clusterCa
object
no
Status surface for one CA. The reconciler fills it in from the parsed CA cert and the CRD spec.
clusterCa.certGeneration
integer
no
0
Monotonic generation of the active signing cert. It increments on a same-key renewal and on a key promotion.
clusterCa.generated
boolean
yes
true when the operator generated this CA, that is, when generateCertificateAuthority == true. false for a BYO CA.
clusterCa.keyGeneration
integer
no
0
Monotonic generation of the active signing key. It increments only on a key replacement.
clusterCa.notAfter
string
yes
RFC3339 notAfter of the current CA cert, which is the signing cert.
clusterCa.rotationPhase
string
no
Staged key-replacement phase. One of idle, key-replace-trust, and key-replace-promote.
clusterCa.trustAnchors
integer
no
Number of CA certs in the trust bundle now.
conditions
array
no
[]
Standard Kubernetes-style condition list. It shows Ready, ListenersValid, and ListenersReady.
kafkaVersion
string
no
Echo of spec.kafkaVersion, for observability.
listeners
array
no
Per-listener resolved addresses. The operator fills them in once ListenersReady=True.
metadataVersion
string
no
The operator-finalized metadata version. It advances only when the version validation passes. It drives the downgrade-window check on the next reconcile.
readyReplicas
integer
no
The same value as StatefulSet.status.readyReplicas.