dapr / dapr/components-contrib
pubsub.kafka : mTLS panics without caCert instead of using system CA trust
- Dominant language
- Go
- Stars
- 602
- Forks
- 580
- Avg merge
- 4d 9h
- Merged PRs (30d)
- 6
Description
## Expected Behavior
When `authType: mtls` is configured and `caCert` is omitted, Dapr should use the sidecar container's system CA trust store to validate the Kafka broker certificate.
This is the documented behavior:
https://github.com/dapr/docs/blob/master/daprdocs/content/en/reference/components-reference/supported-pubsub/setup-apache-kafka.md#L450-L453
This is useful when:
- Kafka is exposed with a publicly trusted server certificate, for example Let's Encrypt.
- Kafka clients authenticate with a separate internal PKI client certificate.
- The Dapr sidecar should retain normal TLS chain and hostname verification through the OS trust store.
## Actual Behavior
Dapr panics during Kafka component initialization when all of the following are true:
- `authType: mtls`
- `clientCert` and `clientKey` are configured
- `caCert` is omitted
- `skipVerify` is left at its secure default (`false`)
Observed with Dapr runtime `1.16.14`, which bundles `components-contrib v1.16.12`. The same code path remains in `components-contrib v1.18.0`.
```text
panic: runtime error: invalid memory address or nil pointer dereference
github.com/dapr/components-contrib/common/component/kafka.updateMTLSAuthInfo
.../common/component/kafka/auth.go:48
```
The cause appears to be:
1. `updateTLSConfig` returns without initializing `config.Net.TLS.Config` when `caCert` is empty and `skipVerify` is `false`.
https://github.com/dapr/components-contrib/blob/v1.18.0/common/component/kafka/auth.go#L53-L70
2. Dapr then calls `updateMTLSAuthInfo` for `authType: mtls`.
https://github.com/dapr/components-contrib/blob/v1.18.0/common/component/kafka/kafka.go#L176-L201
3. `updateMTLSAuthInfo` dereferences `config.Net.TLS.Config` while adding the client certificate.
https://github.com/dapr/components-contrib/blob/v1.18.0/common/component/kafka/auth.go#L41-L50
The underlying Kafka library, IBM Sarama, supports a nil TLS config by creating a TLS 1.2+ config and deriving the broker hostname. A `tls.Config` with `RootCAs` unset uses Go's system trust store.
https://github.com/IBM/sarama/blob/v1.48.1/broker.go#L1950-L1967
## Steps to Reproduce the Problem
1. Deploy Dapr `1.18.0` or another runtime version containing the current Kafka component implementation.
2. Use a Kafka endpoint that:
- requires client certificate authentication;
- has a server certificate chaining to a CA trusted by the Dapr container OS trust store; and
- has a DNS name matching its server certificate.
3. Create a Secret containing a valid Kafka client certificate and its matching private key:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: kafka-client-tls
type: kubernetes.io/tls
data:
tls.crt:
tls.key:
```
4. Apply a Kafka component with mTLS enabled but without `caCert`:
```yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: kafka-pubsub
spec:
type: pubsub.kafka
version: v1
metadata:
- name: brokers
value: "kafka.example.com:443"
- name: authType
value: "mtls"
- name: clientCert
secretKeyRef:
name: kafka-client-tls
key: tls.crt
- name: clientKey
secretKeyRef:
name: kafka-client-tls
key: tls.key
```
5. Start a Dapr-enabled application scoped to `kafka-pubsub`.
6. Observe that the Dapr sidecar panics during component initialization.
A potential fix would be to initialize `config.Net.TLS.Config` before attaching the mTLS client certificate, while leaving `RootCAs` unset when `caCert` is omitted. This would preserve the documented system-trust behavior, TLS hostname verification, and mTLS client authentication.
## Release Note
RELEASE NOTE: **FIX** Prevent Kafka mTLS component panic when `caCert` is omitted and system CA trust is used.
Note : assisted by GPT-5.6 Terra 🤖
Contributor guide
Research direction
Start with common/component/kafka/auth.go, especially updateTLSConfig and updateMTLSAuthInfo, then trace their call from common/component/kafka/kafka.go. Reproduce the mtls configuration with clientCert and clientKey but no caCert. Done means component initialization no longer panics, system CA trust and hostname verification remain enabled, and client-certificate authentication still works.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- stream-processing
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100