Skip to main content
You can configure JSON Web Token (JWT) authentication to a Pulsar cluster using asymmetric (RS256) signing. A private key signs tokens and a public key verifies them on the brokers and proxies, so the signing credential never needs to be distributed to cluster components.

Before you begin

  • Install the following tools.

Keep my-private.key strictly controlled. Anyone who holds the private key can issue valid tokens for any subject, including broker-admin and proxy-admin. Treat it with the same care as a root credential:
  • Store it outside the Kubernetes cluster.
  • Consider storing it in a secrets manager (for example, AWS Secrets Manager, HashiCorp Vault) and only retrieving it when issuing new tokens.

Generate the RSA256 key pair and tokens

Use pulsarctl to generate an RSA256 key pair:
Issue tokens for the broker-admin and proxy-admin subjects using the private key:
Issue a token for the client subject:

Create Kubernetes Secrets for keys and tokens

Only the public key goes into Kubernetes. The private key must never be stored as a cluster Secret.
  • Create the public key Secret:
  • Create the broker-admin token Secret:
  • Create the proxy-admin token Secret:
Replace <broker-admin-token> and <proxy-admin-token> with the tokens generated in the previous step.

Enable JWT authentication for the Pulsar cluster

Add the following configurations to the PulsarBroker object:
  • config.clientAuth: configures the toolset to mount and use the broker-admin token automatically.
  • config.custom: sets Pulsar authentication and authorization properties.
  • pod.secretRefs: mounts the public key Secret as a file inside the pod.
  • pod.vars: exposes the public key path and broker-admin token as environment variables for Pulsar configuration.
On the PulsarProxy object, add the following configurations:
  • config.custom: sets Pulsar authentication and authorization properties.
  • pod.secretRefs: mounts the public key Secret as a file inside the pod.
  • pod.vars: exposes the public key path and broker-admin token as environment variables for Pulsar configuration.

Connect clients to Pulsar

  • Create authorization for the client subject using the broker-admin token:
    Expected output:
    If you are running this command from the toolset pod, pulsarctl reads /pulsar/conf/client.conf which already has the admin service URL and the broker-admin token configured. You can omit the --admin-service-url and --token flags:
  • Produce messages with the client token:
  • Consume messages with the client token:

Verify the configuration

After the pods restart, confirm the broker is using the public key and not a shared secret:
Expected output:
tokenSecretKey must be empty. If it is set, the broker is using symmetric auth instead of RS256.

Configure Pulsar console

The Console CRD does not have a native plain-JWT field. Authentication is configured by injecting environment variables directly via pod.vars and mounting the public key via pod.secretRefs. A single dedicated service account (consoleservice) is used for both the Console backend connection to the broker and the web login. This subject must be in superUserRoles on the broker so it can perform all admin operations, including listing clusters.

Issue the Console service account token

Issue a dedicated RS256 token for the consoleservice subject:
Create a Kubernetes Secret that contains both the token and the public key:
Replace <consoleservice-token> with the token generated above.

Add the Console service account to the broker

Update the PulsarBroker object to include consoleservice in superUserRoles:

Configure the Console CRD

Add the following to the Console object: