dapr / dapr/components-contrib

pubsub.kafka : mTLS panics without  caCert  instead of using system CA trust

Open Beginner friendly
#4,583 0 comments 0 reactions 0 assignees View on GitHub
kind/bug
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.