Chapter 6. Securing a proxy


Secure proxies by using TLS and storing sensitive values in external resources.

6.1. Prerequisites

  • A running Streams for Apache Kafka Proxy instance

6.2. Securing the client-to-proxy connection

Secure client-to-proxy communications using TLS.

This example shows a VirtualKafkaCluster, exposing it to Kafka clients running on the same OpenShift cluster. It uses TLS as the transport protocol so that communication between Kafka clients and the proxy is encrypted.

Example VirtualKafkaCluster configuration

kind: VirtualKafkaCluster
apiVersion: kroxylicious.io/v1alpha1
metadata:
  name: my-cluster
  namespace: my-proxy
spec:
  proxyRef: 
1

    name: simple
  targetKafkaServiceRef: 
2

    name: my-cluster
  ingresses:
    - ingressRef: 
3

        name: cluster-ip
      tls: 
4

        certificateRef:
          name: server-certificate
          kind: Secret

1
Identifies the KafkaProxy resource that this virtual cluster is part of. It must be in the same namespace as the VirtualKafkaCluster.
2
The virtual cluster names the KafkaService to be proxied. It must be in the same namespace as the VirtualKafkaCluster.
3
The virtual cluster can be exposed by one or more ingresses. Each ingress must reference a KafkaProxyIngress in the same namespace as the VirtualKafkaCluster.
4
If the ingress supports TLS, the tls property configures the TLS server certificate to use.

Within a VirtualKafkaCluster, an ingress’s tls property configures TLS for that ingress. The tls.certificateRef specifies the Secret resource holding the TLS server certificate that the proxy uses for clients connecting through this ingress. The referenced KafkaProxyIngress also needs to be configured for TLS.

Example KafkaProxyIngress configuration for TLS

kind: KafkaProxyIngress
apiVersion: kroxylicious.io/v1alpha1
metadata:
  name: cluster-ip
  namespace: my-proxy
spec:
  proxyRef: 
1

    name: simple
  clusterIP: 
2

    protocol: TLS 
3

1
The ingress must reference a KafkaProxy in the same namespace as the KafkaProxyIngress.
2
Exposes the proxy to Kafka clients inside the same OpenShift cluster using a ClusterIP service.
3
The ingress uses TLS as the transport protocol.

You can configure a virtual cluster ingress to request or require Kafka clients to authenticate to the proxy using TLS. This configuration is known as mutual TLS (mTLS), because both the client and the proxy authenticate each other using TLS.

Example VirtualKafkaCluster configuration requiring clients to present a trusted certificate

kind: VirtualKafkaCluster
metadata:
  # ...
spec:
  # ...
  ingresses:
    - ingressRef:
        name: cluster-ip
      tls:
        certificateRef:
          # ...
        trustAnchorRef: 
1

          kind: ConfigMap 
2

          name: trusted-cas 
3

          key: trusted-cas.pem 
4

        tlsClientAuthentication: REQUIRED 
5

1
References a separate OpenShift resource containing the trusted CA certificates.
2
The kind is optional and defaults to ConfigMap.
3
Name of the resource of the given kind, which must exist in the same namespace as the VirtualKafkaCluster.
4
Key identifying the entry in the given resource. The corresponding value must be a set of CA certificates. Supported formats for the bundle are: PEM, PKCS#12, and JKS.
5
Specifies whether client authentication is required (REQUIRED), requested (REQUESTED), or disabled (NONE). If a trustAnchorRef is specified, the default is REQUIRED.

Some older versions of TLS (and SSL before it) are now considered insecure. These versions remain enabled by default in order to maximize interoperability between TLS clients and servers that only support older versions.

If the Kafka cluster than you want to connect to supports newer TLS versions, you can disable the proxy’s support for older, insecure versions. For example, if the Kafka cluster supports TLSv1.1, TLSv1.2 and TLSv1.3 you might choose to enable only TLSv1.3 support. This would reduce the susceptibility to a TLS downgrade attack.

Important

It is good practice to disable insecure protocol versions.

You can restrict which TLS protocol versions the proxy supports for client-to-proxy connections by configuring the protocols property.

Example VirtualKafkaCluster with restricted TLS protocol versions

kind: VirtualKafkaCluster
metadata:
  # ...
spec:
  # ...
  ingresses:
    - ingressRef:
        name: cluster-ip
      tls:
        certificateRef:
          # ...
        protocols: 
1

          allow: 
2

            - TLSv1.3

1
Configures the TLS protocol versions used by the proxy.
2
Lists the protocol versions explicitly allowed for TLS negotiation.

Alternatively, you can use deny to specify protocol versions to exclude.

The names of the TLS protocol versions supported depend on the JVM in the proxy container image. For more information, see SSLContext names.

A cipher suite is a set of cryptographic algorithms that together provide the security guarantees offered by TLS. During TLS negotiation, a server and client agree on a common cipher suite that they both support.

Some older cipher suites are now considered insecure, but may be enabled on the Kafka cluster to allow older clients to connect.

The cipher suites enabled by default in the proxy depend on the JVM used in the proxy image and the TLS protocol version that is negotiated.

To prevent TLS downgrade attacks, you can disable cipher suites known to be insecure or no longer recommended. However, the proxy and the cluster must support at least one cipher suite in common.

Important

It is good practice to disable insecure cipher suites.

You can restrict which TLS cipher suites the proxy uses when negotiating client-to-proxy connections by configuring the cipherSuites property.

Example VirtualKafkaCluster configuration using cipherSuites to allow specific ciphers

kind: VirtualKafkaCluster
metadata:
  # ...
spec:
  # ...
  ingresses:
    - ingressRef:
        name: cluster-ip
      tls:
        certificateRef:
          # ...
        cipherSuites: 
1

          allow: 
2

           - TLS_AES_128_GCM_SHA256
           - TLS_AES_256_GCM_SHA384

1
Configures the cipher suites used by the proxy.
2
Lists the cipher suites explicitly allowed for TLS negotiation.

Alternatively, you can use deny to specify cipher suites to exclude.

The names of the cipher suites supported depend on the JVM in the proxy container image. For more information, see JSSE Cipher Suite Names.

6.3. Securing the proxy-to-broker connection

Secure proxy-to-broker communication using TLS.

By default, the proxy uses the platform’s default trust store when connecting to the proxied cluster over TLS. This works if the cluster’s TLS certificates are signed by a well-known public Certificate Authority (CA), but fails if they’re signed by a private CA instead.

Important

It is good practice to configure trust explicitly, even when proxied cluster’s TLS certificates are signed by a public CA.

This example configures a KafkaService to trust TLS certificates signed by any Certificate Authority (CA) listed in the trusted-cas.pem entry of the ConfigMap named trusted-cas.

Example KafkaService configuration for trusting certificates.

kind: KafkaService
metadata:
  # ...
spec:
  bootstrapServers: kafka.example.com:9092
  tls:
    trustAnchorRef: 
1

      kind: ConfigMap 
2

      name: trusted-cas 
3

      key: trusted-cas.pem 
4

    # ...

1
The trustAnchorRef property references a separate OpenShift resource which contains the CA certificates to be trusted
2
The kind is optional and defaults to ConfigMap.
3
The name of the resource of the given kind. This resource must exist in the same namespace as the KafkaService
4
The key identifies the entry in the given resource. The corresponding value must be a PEM-encoded set of CA certificates.

Some Kafka clusters require mutual TLS (mTLS) authentication. You can configure the proxy to present a TLS client certificate using the KafkaService resource.

The TLS client certificate you provide must have been issued by a Certificate Authority (CA) that’s trusted by the proxied cluster.

This example configures a KafkaService to use a TLS client certificate stored in a Secret named tls-cert-for-kafka.example.com.

Example KafkaService configuration with TLS client authentication.

kind: KafkaService
metadata:
  # ...
spec:
  bootstrapServers: kafka.example.com:9092
  tls:
    trustAnchorRef:
      kind: ConfigMap
      name: trusted-cas
      key: trusted-cas.pem
    certificateRef: 
1

      kind: Secret 
2

      name: tls-cert-for-kafka.example.com 
3

    # ...

1
The certificateRef property identifies the TLS client certificate to use.
2
The kind is optional and defaults to Secret. The Secret should have type: kubernetes.io/tls.
3
The name is the name of the resource of the given kind. This resource must exist in the same namespace as the KafkaService

Some older versions of TLS (and SSL before it) are now considered insecure. These versions remain enabled by default in order to maximize interoperability between TLS clients and servers that only support older versions.

If the Kafka cluster than you want to connect to supports newer TLS versions, you can disable the proxy’s support for older, insecure versions. For example, if the Kafka cluster supports TLSv1.1, TLSv1.2 and TLSv1.3 you might choose to enable only TLSv1.3 support. This would reduce the susceptibility to a TLS downgrade attack.

Important

It is good practice to disable insecure protocol versions.

This example configures a KafkaService to allow only TLS v1.3 when connecting to kafka.example.com.

Example KafkaService with restricted TLS protocol versions.

kind: KafkaService
metadata:
  # ...
spec:
  bootstrapServers: kafka.example.com:9092
  tls:
    # ...
    protocols: 
1

      allow: 
2

        - TLSv1.3

1
The protocols property configures the TLS protocol versions
2
allow lists the versions of TLS which are permitted.

The protocols property also supports deny, if you prefer to list the versions to exclude instead.

The names of the TLS protocol versions supported depend on the JVM in the proxy container image. For more information, see SSLContext names.

A cipher suite is a set of cryptographic algorithms that together provide the security guarantees offered by TLS. During TLS negotiation, a server and client agree on a common cipher suite that they both support.

Some older cipher suites are now considered insecure, but may be enabled on the Kafka cluster to allow older clients to connect.

The cipher suites enabled by default in the proxy depend on the JVM used in the proxy image and the TLS protocol version that is negotiated.

To prevent TLS downgrade attacks, you can disable cipher suites known to be insecure or no longer recommended. However, the proxy and the cluster must support at least one cipher suite in common.

Important

It is good practice to disable insecure cipher suites.

Example KafkaService configured so that the proxy will negotiate TLS connection using only the listed ciphers.

kind: KafkaService
metadata:
  # ...
spec:
  bootstrapServers: kafka.example.com:9092
  tls:
    # ...
    cipherSuites: 
1

      allow: 
2

       - TLS_AES_128_GCM_SHA256
       - TLS_AES_256_GCM_SHA384

1
The cipherSuites object configures the cipher suites.
2
allow lists the cipher suites which are permitted.

The cipherSuites property also supports deny, if you prefer to list the cipher suites to exclude instead.

The names of the cipher suites supported depend on the JVM in the proxy container image. For more information, see JSSE Cipher Suite Names.

6.4. Securing filters

Secure filters by using the security features provided by each filter and storing sensitive values in external resources such as an OpenShift Secret.

6.4.1.1. Template use and value interpolation

Interpolation is supported in spec.configTemplate for the automatic substitution of placeholder values at runtime. This allows security-sensitive values, such as passwords or keys, to be specified in OpenShift Secret resources rather than directly in the KafkaProtocolFilter resource. Likewise, things like trusted CA certificates can be defined in ConfigMap resources.

The operator determines which Secret and ConfigMap resources are referenced by a KafkaProtocolFilter resource and declares them as volumes in the proxy Pod, mounted into the proxy container. This example shows how to configure the RecordEncryptionFilter using a Vault KMS deployed in the same OpenShift cluster.

Example KafkaProtocolFilter configuration

kind: KafkaProtocolFilter
metadata:
  # ...
spec:
  type: RecordEncryption 
1

  configTemplate: 
2

    kms: VaultKmsService
    kmsConfig:
      vaultTransitEngineUrl: http://vault.vault.svc.cluster.local:8200/v1/transit
      vaultToken:
        password: ${secret:vault:token} 
3

    selector: TemplateKekSelector
    selectorConfig:
      template: "$(topicName)" 
4

1
The type is the Java class name of the proxy filter. If the unqualified name is ambiguous, it must be qualified by the filter package name.
2
The KafkaProtocolFilter requires a configTemplate, which supports interpolation references.
3
The password uses an interpolation reference, enclosed by ${ and } instead of a literal value. The operator supplies the value at runtime from the specified Secret.
4
The selector template is interpreted by the proxy. It uses different delimiters, $( and ), than the interpolation reference.

6.4.1.2. Structure of interpolation references

Let’s look at the example interpolation reference ${secret:vault:token} in more detail.

It starts with ${ and ends with }. Between these, it is broken into three parts, separated by colons (:):

  • secret is a provider. Supported providers are secret and configmap (note the use of lower case).
  • vault is a path. The interpretation of the path depends on the provider.
  • token is a key. The interpretation of the key also depends on the provider.

For both secret and configmap providers:

  • The path is interpreted as the name of a Secret or ConfigMap resource in the same namespace as the KafkaProtocolFilter resource.
  • The key is interpreted as a key in the data property of the Secret or ConfigMap resource.
Red Hat logoGithubredditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat Documentation

Legal Notice

Theme

© 2026 Red Hat
Back to top