Skip to main content
Use mutual TLS (mTLS) to authenticate clients with certificates. The broker validates the certificate chain and uses the client certificate’s common name (CN) as its Pulsar role.

Before you begin

  • Upgrade to StreamNative Operator Helm chart 0.20.6 (Operator v0.20.18) and update its CRDs. This release preserves clientAuth when server authentication is configured through custom instead of the typed authentication field. See Upgrade StreamNative Operator.
  • Prepare a CA, a server certificate and private key, and a separate client certificate and private key for the broker’s internal client.
  • Check that the CA, server certificate, and client certificates are within their validity periods. Renew expired certificates and update their Secrets before testing connections.
  • Include the Service and advertised broker DNS names in the server certificate’s subject alternative names (SANs). Include serverAuth usage on the server certificate and clientAuth usage on client certificates.
  • Choose the client certificate common names and grant their corresponding roles the required permissions.
The examples use Private Cloud Pulsar 4.2.1.17 with the API key authorization provider. They assume an existing broker deployment with storage and networking already configured.

Create certificate Secrets

Create two Secrets in the broker’s namespace. Each Secret contains tls.crt, tls.key, and ca.crt. Supply the leaf certificate and any required intermediate certificates in tls.crt.
The examples assume the internal client’s CN is broker-admin. Give each application its own client certificate and role. Distribute the trusted CA, not its signing private key, to components and applications.

Configure the server and its internal client

Merge these settings into your PulsarBroker:
Configure spec.tls before, or in the same update as, enabling clientAuth.mtls or custom broker-client TLS properties. Client-side TLS settings alone do not create server TLS endpoints. The Operator mounts server material under /etc/tls/pulsar-broker and client material under /mnt/client/mtls. The typed client configuration generates:
The generated ConfigMap uses the PULSAR_PREFIX_ form of these keys. A mounted certificate Secret alone does not prove that the internal client’s authentication properties were generated correctly. If you configure server authentication through spec.config.custom, you can omit the typed authentication field and retain typed clientAuth.mtls on Operator 0.20.16. Custom authentication properties take precedence over typed values. See Authentication overview. For a proxy or Functions Worker, clientAuth.mtls configures its connection to brokers. Configure the TLS broker endpoint and the certificate role’s permissions for that component. Do not assume that enabling TLS on the component’s own server also changes its broker connection URL.

Connect a client

Use the actual TLS endpoints. The default broker ports are 6651 for pulsar+ssl:// and 8443 for HTTPS. Operator-generated non-TLS brokerServiceUrl and webServiceUrl values must not be reused as TLS client URLs. With the default cluster_tls listener, produce messages as follows:
Start a consumer first in another terminal using the same connection options and consume persistent://<tenant>/<namespace>/mtls-check -s mtls-check -n 3. Use the listener name configured by your deployment if it differs from cluster_tls. For a Java application, enable CA and hostname verification:
Import PulsarClient and AuthenticationFactory from org.apache.pulsar.client.api, and close the client when the application exits. Check an administrative HTTPS endpoint with the client certificate:
For an authorized administrative CN, expect HTTP 200. The certificate’s SANs must match the hostname in the URL.

Verify authentication and internal operations

Check all of the following after the broker becomes Ready: For example, use an administrative pulsar-admin client with HTTPS, CA, and TLS authentication settings to set and retrieve a policy on an existing test topic:
Use the same connection options with topics get-retention persistent://<tenant>/<namespace>/mtls-check to confirm the value. This example retains messages for 10 minutes without a size limit. If you set a size limit, make it larger than the namespace’s backlog quota. A lower retention limit can cause HTTP 412. If Pods are Ready but topic policies fail, inspect broker logs and generated client properties. Enabling TLS while connecting to pulsar://...:6650 can cause handshake failures; depending on the client path, a configuration error can also appear. Verify the URL scheme, port, listener, CA, hostname, and internal client role together.