KafkaUser
Expand a field to see its description, example, and default behavior. Nested fields are grouped under their parent.
Required fields must be present when their parent object exists. [] denotes an array item; {key} denotes a map value. status is written by the operator. Reconcile-time checks and runtime defaults can add requirements beyond the schema.
Examples are illustrative JSON values. Open “View JSON example” for an object or array. Adapt names, endpoints, and credentials to your cluster. Kubernetes applies schema defaults when the containing object exists. Runtime and omission notes describe operator behavior. Status examples show reported data.
Runtime notes and domain examples were reviewed against operator source at b409b56.
View the complete CRD manifest at 618d621Example manifest
This example includes the required spec fields. Adapt its values and create any referenced resources before applying it.
apiVersion: krabka.io/v1alpha1
kind: KafkaUser
metadata:
name: example
namespace: default
labels:
krabka.io/cluster: my-cluster
spec:
authentication:
type: scram-sha-512
iterations: 8192
passwordLength: 32
No fields match. Change the search or reset the filters.
krabka.io/v1alpha1
Complete OpenAPI schema (JSON)
{
"description": "Auto-generated derived type for KafkaUserSpec via `CustomResource`",
"properties": {
"spec": {
"properties": {
"authentication": {
"description": "Tagged enum on `type`, in the same shape as Strimzi.\n\nThe wire shape is flat and Strimzi-compatible. `type` is the discriminator,\nand the per-variant config fields are siblings of `type`. The custom\n`schema_with` writes a structural schema by hand, because the\n`StructuralSchemaRewriter` of kube-rs 3.x panics when `oneOf` branches\nshare a `type` property with different `enum` values. That is the default\nschemars output for tagged-union enums. This is the same workaround as\n`Storage` in `kafka_node_pool.rs`.\n\nThe operator enforces the cross-variant constraints at reconcile time, and\nthe apiserver does not. One such constraint is that `iterations` is valid\nonly when `type=scram-sha-512`.",
"properties": {
"iterations": {
"maximum": 1000000,
"minimum": 4096,
"type": "integer"
},
"maxLifetime": {
"type": "string"
},
"passwordLength": {
"maximum": 256,
"minimum": 16,
"type": "integer"
},
"renewBeforeExpiry": {
"type": "string"
},
"renewalDays": {
"maximum": 3650,
"minimum": 1,
"type": "integer"
},
"renewers": {
"items": {
"pattern": "^User:.+$",
"type": "string"
},
"type": "array"
},
"type": {
"enum": [
"scram-sha-512",
"scram-sha-256",
"tls",
"tls-external",
"delegation-token"
],
"type": "string"
},
"validityDays": {
"maximum": 36500,
"minimum": 1,
"type": "integer"
}
},
"required": [
"type"
],
"type": "object"
},
"authorization": {
"description": "Authorization is optional. A user with no ACLs can still\nauthenticate. When this field is absent, the operator skips ACL\nreconciliation.",
"nullable": true,
"oneOf": [
{
"required": [
"type"
]
}
],
"properties": {
"acls": {
"default": [],
"items": {
"description": "One rule from `spec.authorization.acls`. The operator expands it into one\n`(resource, operation, host, type)` tuple per `operations` entry at\nreconcile time.",
"properties": {
"host": {
"description": "Source-address pattern. `\"*\"` is the wildcard. Defaults to `\"*\"` when\nomitted.",
"type": "string"
},
"operations": {
"description": "Non-empty list. The reconciler refuses an empty `operations` with\n`Ready=False reason=InvalidSpec`.",
"items": {
"description": "All 11 Kafka ACL operations. Matches the discriminants in\n`org.apache.kafka.common.acl.AclOperation`.",
"enum": [
"All",
"Read",
"Write",
"Create",
"Delete",
"Alter",
"Describe",
"ClusterAction",
"DescribeConfigs",
"AlterConfigs",
"IdempotentWrite"
],
"type": "string"
},
"type": "array"
},
"resource": {
"properties": {
"name": {
"type": "string"
},
"patternType": {
"default": "literal",
"description": "`literal` for an exact match, or `prefixed` for resources whose name\nstarts with `name`. Defaults to `literal`.",
"enum": [
"literal",
"prefixed"
],
"type": "string"
},
"type": {
"enum": [
"topic",
"group",
"cluster",
"transactional-id"
],
"type": "string"
}
},
"required": [
"name",
"type"
],
"type": "object"
},
"type": {
"default": "allow",
"description": "`allow` or `deny`; defaults to `allow`.",
"enum": [
"allow",
"deny"
],
"type": "string"
}
},
"required": [
"operations",
"resource"
],
"type": "object"
},
"type": "array"
},
"type": {
"enum": [
"simple"
],
"type": "string"
}
},
"type": "object"
},
"quotas": {
"description": "Optional per-user client quotas (KIP-13/124/257). This field maps\nonto Kafka's `(user)` quota entity through `AlterClientQuotas`, which\nis `api_key` 49. When the field is absent, the operator does not touch\nthe broker's quota state. When the field is present, the operator\ndrives the broker's quota keys for `User:<name>` toward the spec. It\nsets the configured fields and tombstones the omitted ones.",
"nullable": true,
"properties": {
"consumerByteRate": {
"description": "Maximum consume-side bytes/sec. Backed by `consumer_byte_rate`.",
"format": "int32",
"minimum": 0,
"nullable": true,
"type": "integer"
},
"controllerMutationRate": {
"description": "KIP-599 controller-mutation rate in creates and deletes per second.\nBacked by `controller_mutation_rate`.",
"format": "double",
"nullable": true,
"type": "number"
},
"producerByteRate": {
"description": "Maximum produce-side bytes/sec. Backed by `producer_byte_rate`.",
"format": "int32",
"minimum": 0,
"nullable": true,
"type": "integer"
},
"requestPercentage": {
"description": "Maximum percentage of a request-handler thread's time that the user\ncan consume, in the range `0..=100`. Backed by `request_percentage`.",
"format": "int32",
"maximum": 100,
"minimum": 0,
"nullable": true,
"type": "integer"
}
},
"type": "object"
}
},
"required": [
"authentication"
],
"type": "object"
},
"status": {
"nullable": true,
"properties": {
"conditions": {
"default": [],
"description": "Standard Kubernetes-style condition list. It shows `Ready`.",
"items": {
"properties": {
"lastTransitionTime": {
"description": "RFC3339 timestamp.",
"type": "string"
},
"message": {
"description": "Human-readable message.",
"type": "string"
},
"reason": {
"description": "CamelCase machine reason.",
"type": "string"
},
"status": {
"description": "`True`, `False`, or `Unknown`.",
"type": "string"
},
"type": {
"description": "For example, `Ready`.",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object"
},
"type": "array"
},
"delegationTokenExpiryTimestampMs": {
"description": "Current `expiry_timestamp_ms` of the operator-managed delegation\ntoken. Each successful renew extends it. The operator compares it\nagainst `now` to decide when to renew, as\n`spec.authentication.renewBeforeExpiry` specifies.",
"format": "int64",
"nullable": true,
"type": "integer"
},
"delegationTokenId": {
"description": "Persisted `token_id`, a UUID, of the operator-managed delegation\ntoken for this user. The operator uses it across reconciles to find the\nsame token with `DescribeDelegationToken`. It is present once the\noperator has issued a token with `CreateDelegationToken`.",
"nullable": true,
"type": "string"
},
"delegationTokenMaxTimestampMs": {
"description": "Token's absolute upper bound, which is `max_timestamp_ms`. A renew can\nnever push `expiry_timestamp_ms` past this bound. The operator stops\nthe renews and surfaces `TokenExpiring` once no more extension is\npossible.",
"format": "int64",
"nullable": true,
"type": "integer"
},
"external": {
"default": false,
"description": "`true` once the operator has reconciled a credential-less user with\n`type: tls-external`. It appears in `kubectl describe ku`, so that\noperators can see that the operator does not own this user's\ncredentials.",
"type": "boolean"
},
"observedGeneration": {
"description": "`metadata.generation` of the last successfully-reconciled spec.",
"format": "int64",
"nullable": true,
"type": "integer"
},
"quotasInSync": {
"default": false,
"description": "True once the operator has reflected the spec's `quotas`, if any, in\nthe broker's `(user)` client-quota state. False when `spec.quotas` is\n`None`, because the operator then does not touch broker quotas.",
"type": "boolean"
},
"scramSha256": {
"default": false,
"description": "True once SCRAM-SHA-256 credentials are provisioned.",
"type": "boolean"
},
"scramSha512": {
"default": false,
"description": "True once SCRAM-SHA-512 credentials are provisioned.",
"type": "boolean"
},
"secret": {
"description": "Name of the Kubernetes Secret holding the user's password.",
"nullable": true,
"type": "string"
},
"tls": {
"default": false,
"description": "`true` once a TLS user has a current cert Secret. It has the same\nshape as `scram_sha512`.",
"type": "boolean"
},
"tlsCertNotAfter": {
"description": "RFC3339 timestamp of the user cert's `notAfter`. Present when\n`tls == true`.",
"nullable": true,
"type": "string"
},
"tlsPrincipal": {
"description": "The principal string that the operator pinned in ACLs. It is\n`User:CN=alice` for TLS users, and `User:alice` for SCRAM and\n`tls-external` users. It is always filled in when the user is\nprovisioned. It is load-bearing for the debug of ACL-match problems.",
"nullable": true,
"type": "string"
},
"username": {
"description": "Effective Kafka principal name. It matches `metadata.name`.",
"nullable": true,
"type": "string"
}
},
"type": "object"
}
},
"required": [
"spec"
],
"title": "KafkaUser",
"type": "object"
}
spec
spec
object
Required
3 fields
- Example
-
View JSON example
{ "authentication": { "type": "scram-sha-512", "iterations": 8192, "passwordLength": 32 } } - Default No schema default
- Not declared
authentication
object
Required
8 fields
Tagged enum on type, in the same shape as Strimzi.
The wire shape is flat and Strimzi-compatible. type is the discriminator, and the per-variant config fields are siblings of type. The custom schema_with writes a structural schema by hand, because the StructuralSchemaRewriter of kube-rs 3.x panics when oneOf branches share a type property with different enum values. That is the default schemars output for tagged-union enums. This is the same workaround as Storage in kafka_node_pool.rs.
The operator enforces the cross-variant constraints at reconcile time, and the apiserver does not. One such constraint is that iterations is valid only when type=scram-sha-512.
- Example
-
View JSON example
{ "type": "scram-sha-512", "iterations": 8192, "passwordLength": 32 } - Default No schema default
- Not declared
iterations
integer
Optional
- Example
-
8192 - Default Runtime / omission
8192 for SCRAM-SHA-512 or SCRAM-SHA-256. Applies only to SCRAM authentication.
Validation and schema details
- Maximum
1000000
- Minimum
4096
maxLifetime
string
Optional
- Example
-
"7d" - Default Runtime / omission
Use the broker's delegation_token_max_lifetime (documented default 7d); the broker also caps an explicit lifetime.
passwordLength
integer
Optional
- Example
-
32 - Default Runtime / omission
32 raw bytes (44 base64 characters) for a generated SCRAM password. Existing password Secrets are retained.
Validation and schema details
- Maximum
256
- Minimum
16
renewBeforeExpiry
string
Optional
- Example
-
"24h" - Default Runtime / omission
24h for delegation-token authentication. The controller requires at least 60s.
renewalDays
integer
Optional
- Example
-
30 - Default Runtime / omission
30 days before expiry for TLS certificate renewal. Applies only to type tls.
Validation and schema details
- Maximum
3650
- Minimum
1
renewers
array
Optional
1 field
- Example
-
View JSON example
[ "User:bob" ]
- Default Runtime / omission
[] for delegation-token authentication.
[]
string
Array item
- Example
-
"User:bob" - Default No independent default
- Defined by the parent
Validation and schema details
- Pattern
"^User:.+$"
type
string
Required
- Example
-
"scram-sha-512" - Default No schema default
- Not declared
"scram-sha-512""scram-sha-256""tls""tls-external""delegation-token"
validityDays
integer
Optional
- Example
-
365 - Default Runtime / omission
365 days for TLS client certificates. Applies only to type tls.
Validation and schema details
- Maximum
36500
- Minimum
1
authorization
object | null
Optional
3 fields
Authorization is optional. A user with no ACLs can still authenticate. When this field is absent, the operator skips ACL reconciliation.
- Example
-
View JSON example
{ "type": "simple", "acls": [ { "resource": { "type": "topic", "name": "orders", "patternType": "literal" }, "operations": [ "Read", "Describe" ], "host": "*", "type": "allow" } ] } - Default Runtime / omission
Absent: the operator skips ACL reconciliation.
Validation and schema details
- Exactly one option must match
[ { "required": [ "type" ] } ]
acls
array
Optional
1 field
- Example
-
View JSON example
[ { "operations": [ "Read", "Describe" ], "resource": { "name": "orders", "type": "topic" } } ] - Default Schema default
[]
[]
object
Array item
4 fields
One rule from spec.authorization.acls. The operator expands it into one (resource, operation, host, type) tuple per operations entry at reconcile time.
- Example
-
View JSON example
{ "operations": [ "Read", "Describe" ], "resource": { "name": "orders", "type": "topic" } } - Default No independent default
- Defined by the parent
host
string
Optional
Source-address pattern. "*" is the wildcard. Defaults to "*" when omitted.
- Example
-
"*" - Default Runtime / omission
- (all source addresses).
operations
array
Required
1 field
Non-empty list. The reconciler refuses an empty operations with Ready=False reason=InvalidSpec.
- Example
-
View JSON example
[ "Read", "Describe" ]
- Default No schema default
- Not declared
[]
string
Array item
All 11 Kafka ACL operations. Matches the discriminants in org.apache.kafka.common.acl.AclOperation.
- Example
-
"All" - Default No independent default
- Defined by the parent
"All""Read""Write""Create""Delete""Alter""Describe""ClusterAction""DescribeConfigs""AlterConfigs""IdempotentWrite"
resource
object
Required
3 fields
- Example
-
View JSON example
{ "name": "orders", "type": "topic" } - Default No schema default
- Not declared
name
string
Required
- Example
-
"orders" - Default No schema default
- Not declared
patternType
string
Optional
literal for an exact match, or prefixed for resources whose name starts with name. Defaults to literal.
- Example
-
"literal" - Default Schema default
"literal"
"literal""prefixed"
type
string
Required
- Example
-
"topic" - Default No schema default
- Not declared
"topic""group""cluster""transactional-id"
type
string
Optional
allow or deny; defaults to allow.
- Example
-
"allow" - Default Schema default
"allow"
"allow""deny"
type
string
Required
- Example
-
"simple" - Default No schema default
- Not declared
"simple"
oneOf option 1
any
Schema option
spec.authorization oneOf option 1
- Example
-
View JSON example
{ "type": "simple", "acls": [ { "resource": { "type": "topic", "name": "orders", "patternType": "literal" }, "operations": [ "Read", "Describe" ], "host": "*", "type": "allow" } ] } - Default Runtime / omission
Absent: the operator skips ACL reconciliation.
quotas
object | null
Optional
4 fields
Optional per-user client quotas (KIP-13/124/257). This field maps onto Kafka's (user) quota entity through AlterClientQuotas, which is api_key 49. When the field is absent, the operator does not touch the broker's quota state. When the field is present, the operator drives the broker's quota keys for User:<name> toward the spec. It sets the configured fields and tombstones the omitted ones.
- Example
-
View JSON example
{ "producerByteRate": 1048576, "consumerByteRate": 2097152, "requestPercentage": 55, "controllerMutationRate": 10.5 } - Default Runtime / omission
Absent: the operator does not manage quotas. {} removes all managed quota overrides.
consumerByteRate
integer | null (int32)
Optional
Maximum consume-side bytes/sec. Backed by consumer_byte_rate.
- Example
-
2097152 - Default Runtime / omission
Absent quotas: leave broker state unchanged. When quotas is present, omit this field to remove this quota override.
Validation and schema details
- Minimum
0
controllerMutationRate
number | null (double)
Optional
KIP-599 controller-mutation rate in creates and deletes per second. Backed by controller_mutation_rate.
- Example
-
10.5 - Default Runtime / omission
Absent quotas: leave broker state unchanged. When quotas is present, omit this field to remove this quota override.
producerByteRate
integer | null (int32)
Optional
Maximum produce-side bytes/sec. Backed by producer_byte_rate.
- Example
-
1048576 - Default Runtime / omission
Absent quotas: leave broker state unchanged. When quotas is present, omit this field to remove this quota override.
Validation and schema details
- Minimum
0
requestPercentage
integer | null (int32)
Optional
Maximum percentage of a request-handler thread's time that the user can consume, in the range 0..=100. Backed by request_percentage.
- Example
-
55 - Default Runtime / omission
Absent quotas: leave broker state unchanged. When quotas is present, omit this field to remove this quota override.
Validation and schema details
- Maximum
100
- Minimum
0
status
status
object | null
Optional
14 fields
- Example
-
View JSON example
{ "conditions": [ { "lastTransitionTime": "2026-10-05T12:00:00Z", "message": "The resource is ready.", "reason": "Reconciled", "status": "True", "type": "Ready" } ] } - Default No schema default
- Not declared
conditions
array
Optional
1 field
Standard Kubernetes-style condition list. It shows Ready.
- Example
-
View JSON example
[ { "lastTransitionTime": "2026-10-05T12:00:00Z", "message": "The resource is ready.", "reason": "Reconciled", "status": "True", "type": "Ready" } ] - Default Schema default
[]
[]
object
Array item
5 fields
- Example
-
View JSON example
{ "lastTransitionTime": "2026-10-05T12:00:00Z", "message": "The resource is ready.", "reason": "Reconciled", "status": "True", "type": "Ready" } - Default No schema default
- Not declared
lastTransitionTime
string
Required
RFC3339 timestamp.
- Example
-
"2026-10-05T12:00:00Z" - Default No schema default
- Not declared
message
string
Required
Human-readable message.
- Example
-
"The resource is ready." - Default No schema default
- Not declared
reason
string
Required
CamelCase machine reason.
- Example
-
"Reconciled" - Default No schema default
- Not declared
status
string
Required
True, False, or Unknown.
- Example
-
"True" - Default No schema default
- Not declared
type
string
Required
For example, Ready.
- Example
-
"Ready" - Default No schema default
- Not declared
delegationTokenExpiryTimestampMs
integer | null (int64)
Optional
Current expiry_timestamp_ms of the operator-managed delegation token. Each successful renew extends it. The operator compares it against now to decide when to renew, as spec.authentication.renewBeforeExpiry specifies.
- Example
-
1 - Default No schema default
- Not declared
delegationTokenId
string | null
Optional
Persisted token_id, a UUID, of the operator-managed delegation token for this user. The operator uses it across reconciles to find the same token with DescribeDelegationToken. It is present once the operator has issued a token with CreateDelegationToken.
- Example
-
"019bbdb3-fec4-7780-9978-8805004f5d96" - Default No schema default
- Not declared
delegationTokenMaxTimestampMs
integer | null (int64)
Optional
Token's absolute upper bound, which is max_timestamp_ms. A renew can never push expiry_timestamp_ms past this bound. The operator stops the renews and surfaces TokenExpiring once no more extension is possible.
- Example
-
1 - Default No schema default
- Not declared
external
boolean
Optional
true once the operator has reconciled a credential-less user with type: tls-external. It appears in kubectl describe ku, so that operators can see that the operator does not own this user's credentials.
- Example
-
false - Default Schema default
false
observedGeneration
integer | null (int64)
Optional
metadata.generation of the last successfully-reconciled spec.
- Example
-
1 - Default No schema default
- Not declared
quotasInSync
boolean
Optional
True once the operator has reflected the spec's quotas, if any, in the broker's (user) client-quota state. False when spec.quotas is None, because the operator then does not touch broker quotas.
- Example
-
false - Default Schema default
false
scramSha256
boolean
Optional
True once SCRAM-SHA-256 credentials are provisioned.
- Example
-
false - Default Schema default
false
scramSha512
boolean
Optional
True once SCRAM-SHA-512 credentials are provisioned.
- Example
-
false - Default Schema default
false
secret
string | null
Optional
Name of the Kubernetes Secret holding the user's password.
- Example
-
"alice" - Default No schema default
- Not declared
tls
boolean
Optional
true once a TLS user has a current cert Secret. It has the same shape as scram_sha512.
- Example
-
false - Default Schema default
false
tlsCertNotAfter
string | null
Optional
RFC3339 timestamp of the user cert's notAfter. Present when tls == true.
- Example
-
"2027-10-05T00:00:00Z" - Default No schema default
- Not declared
tlsPrincipal
string | null
Optional
The principal string that the operator pinned in ACLs. It is User:CN=alice for TLS users, and User:alice for SCRAM and tls-external users. It is always filled in when the user is provisioned. It is load-bearing for the debug of ACL-match problems.
- Example
-
"User:CN=alice" - Default No schema default
- Not declared
username
string | null
Optional
Effective Kafka principal name. It matches metadata.name.
- Example
-
"alice" - Default No schema default
- Not declared
Resource schema
Resource schema
object
Resource schema
Auto-generated derived type for KafkaUserSpec via CustomResource
- Example
-
View JSON example
{ "apiVersion": "krabka.io/v1alpha1", "kind": "KafkaUser", "metadata": { "name": "example", "namespace": "default", "labels": { "krabka.io/cluster": "my-cluster" } }, "spec": { "authentication": { "type": "scram-sha-512", "iterations": 8192, "passwordLength": 32 } } } - Default No resource default
- None