# Use SASL/GSSAPI Authentication in Confluent Platform

<a id="kafka-sasl-auth-gssapi"></a>

## Configure GSSAPI in Confluent Platform clusters

### SASL/GSSAPI overview

SASL/GSSAPI is for organizations using Kerberos (for example, by using Active
Directory). You don’t need to install a new server just for Confluent Platform. Ask your
Kerberos administrator for a principal for each Confluent Server broker in your Confluent Platform cluster and
for every operating system user that will access Confluent Platform with Kerberos authentication
(via clients and tools).

If you don’t already have a Kerberos server, your Linux vendor likely has packages
for Kerberos and a short guide on how to install and configure it
([Ubuntu](https://help.ubuntu.com/community/Kerberos), [Red Hat](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Managing_Smart_Cards/installing-kerberos.html)). Note that if you are using Oracle Java, you must download JCE policy files for your Java version and copy them to `$JAVA_HOME/jre/lib/security`. You must create these principals yourself using the following commands:

```bash
sudo /usr/sbin/kadmin.local -q 'addprinc -randkey kafka/{hostname}@{REALM}'
sudo /usr/sbin/kadmin.local -q "ktadd -k /etc/security/keytabs/{keytabname}.keytab kafka/{hostname}@{REALM}"
```

It is a Kerberos requirement that all your hosts can be resolved with their
fully-qualified domain names (FQDNs).

The remainder of this page will show you how to configure SASL/GSSAPI for each
component in the Confluent Platform.

#### GSSAPI logging

To enable SASL/GSSAPI debug output, you can set the `sun.security.krb5.debug`
system property to `true`. For example:

```bash
export KAFKA_OPTS=-Dsun.security.krb5.debug=true
kafka-server-start etc/kafka/server.properties
```

<a id="sasl-gssapi-broker"></a>

### Brokers

Configure all brokers in the Kafka cluster to accept secure connections from clients. Any configuration changes made to the broker will require a [rolling restart](../../../../kafka/post-deployment.md#rolling-restart).

Enable security for Kafka brokers as described in the section below. Additionally, if you are using Confluent Control Center or Auto Data Balancer, configure your brokers for:

* [Confluent Metrics Reporter](#sasl-gssapi-metrics-reporter)

<a id="jaas-config"></a>

#### JAAS

#### NOTE
While use of separate JAAS files is supported, it is *not* the recommended
approach. Instead, use the listener configuration specified in
[Configuration](#auth-sasl-gssapi-config) to replace steps 1 and 2 below.
Note that step 3 below is still required.

1. First create the broker’s JAAS configuration file in each Kafka broker’s
   configuration directory, let’s call it `kafka_server_jaas.conf` for this example.
2. In each broker’s JAAS file, configure a `KafkaServer` section with a unique
   principal and keytab, i.e., secret key, for each broker. Make sure the keytabs
   configured in the JAAS file are readable by the operating system user who is
   starting the Kafka broker.
   ```bash
   // Specifies a unique keytab and principal name for each broker
   KafkaServer {
       com.sun.security.auth.module.Krb5LoginModule required
       useKeyTab=true
       storeKey=true
       keyTab="/etc/security/keytabs/kafka_server.keytab"
       principal="kafka/kafka1.hostname.com@EXAMPLE.COM";
   };
   ```

<a id="auth-sasl-gssapi-config"></a>

#### Configuration

1. Enable GSSAPI mechanism in the `server.properties` file of every broker.
   ```bash
   # List of enabled mechanisms, can be more than one
   sasl.enabled.mechanisms=GSSAPI

   # Specify one of of the SASL mechanisms
   sasl.mechanism.inter.broker.protocol=GSSAPI
   ```

1. If you want to enable SASL for interbroker communication, add the following
   to the broker properties file (it defaults to `PLAINTEXT`).
   Set the protocol to:
   * `SASL_SSL`: if TLS/SSL encryption is enabled (TLS/SSL encryption should always be used if SASL mechanism is PLAIN)
   * `SASL_PLAINTEXT`: if TLS/SSL encryption is not enabled

   ```bash
   # Configure SASL_SSL if TLS/SSL encryption is enabled, otherwise configure SASL_PLAINTEXT
   security.inter.broker.protocol=SASL_SSL
   ```
2. Tell the Kafka brokers on which ports to listen for client and interbroker
   `SASL` connections. You must configure `listeners`, and optionally
   `advertised.listeners` if the value is different from `listeners`.
   Set the listener to:
   * `SASL_SSL`: if TLS/SSL encryption is enabled (TLS/SSL encryption should always be used if SASL mechanism is PLAIN)
   * `SASL_PLAINTEXT`: if TLS/SSL encryption is not enabled

   ```none
   # With TLS/SSL encryption
   listeners=SASL_SSL://kafka1:9093
   advertised.listeners=SASL_SSL://localhost:9093

   # Without TLS/SSL encryption
   listeners=SASL_PLAINTEXT://kafka1:9093
   advertised.listeners=SASL_PLAINTEXT://localhost:9093
   ```
3. Configure both `SASL_SSL` and `PLAINTEXT` ports if:
   * SASL is not enabled for interbroker communication
   * Some clients connecting to the cluster do not use SASL

   Example SASL listeners with TLS/SSL encryption, mixed with PLAINTEXT listeners
   ```none
   # With TLS/SSL encryption
   listeners=PLAINTEXT://kafka1:9092,SASL_SSL://kafka1:9093
   advertised.listeners=PLAINTEXT://localhost:9092,SASL_SSL://localhost:9093

   # Without TLS/SSL encryption
   listeners=PLAINTEXT://kafka1:9092,SASL_PLAINTEXT://kafka1:9093
   advertised.listeners=PLAINTEXT://localhost:9092,SASL_PLAINTEXT://localhost:9093
   ```

1. If you are not using a separate JAAS configuration file to configure JAAS, then configure
   JAAS for the Kafka broker listener as follows:
   ```none
   listener.name.sasl_ssl.gssapi.sasl.jaas.config=com.sun.security.auth.module.Krb5LoginModule required \
     useKeyTab=true \
     storeKey=true \
     keyTab="/etc/security/keytabs/kafka_server.keytab" \
     principal="kafka/kafka1.hostname.com@EXAMPLE.COM";
   ```
2. When using GSSAPI, configure a service name that matches the primary
   name of the Brokers configured in the Broker JAAS file. In earlier JAAS file
   examples, with `principal="kafka/kafka1.hostname.com@EXAMPLE.COM";`, the primary is “kafka”.
   ```bash
   sasl.kerberos.service.name=kafka
   ```

#### Run

If using a separate JAAS file, pass the name of the JAAS file as a JVM parameter when you start each Kafka broker:

```bash
export KAFKA_OPTS="-Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf"
kafka-server-start etc/kafka/server.properties
```

Here are some optional settings that you can pass in as a JVM parameter when you start each broker from the command line.

`zookeeper.sasl.client`
: Use to enable SASL authentication to ZooKeeper.
  <br/>
  * Type: Boolean
  * Default: true
  * Usage example: To pass the parameter as a JVM parameter when you start the
    broker, specify `-Dzookeeper.sasl.client=true`.

`zookeeper.sasl.client.username`
: For SASL authentication to ZooKeeper, to change the username set the system property
  to use the appropriate name.
  <br/>
  * Type: string
  * Default: zookeeper
  * Usage example: To pass the parameter as a JVM parameter when you start the
    broker, specify `-Dzookeeper.sasl.client.username=zk`.

`zookeeper.sasl.clientconfig`
: Specifies the context key in the JAAS login file. This is used to change the section
  name for SASL authentication to ZooKeeper.
  <br/>
  * Type: string
  * Default: Client
  * Usage example: To pass the parameter as a JVM parameter when you start the
    broker, specify `-Dzookeeper.sasl.clientconfig=ZkClient`.

`-Djava.security.krb5.conf`
: Optionally specify the path to the `krb5.conf` file (see [JDK’s Kerberos Requirements](https://docs.oracle.com/javase/8/docs/technotes/guides/security/jgss/tutorials/KerberosReq.html) for more details)

<a id="sasl-gssapi-clients"></a>

### Clients

The new Producer and Consumer clients support security for Kafka versions 0.9.0 and higher.

If you are using the Kafka Streams API, you can read on how to configure equivalent
[SSL](/platform/current/clients/javadocs/javadoc/org/apache/kafka/common/config/SslConfigs.html) and
[SASL](/platform/current/clients/javadocs/javadoc/org/apache/kafka/common/config/SaslConfigs.html) parameters.

1. Configure the following properties in a client properties file `client.properties`.
   ```bash
   sasl.mechanism=GSSAPI
   # Configure SASL_SSL if TLS/SSL encryption is enabled, otherwise configure SASL_PLAINTEXT
   security.protocol=SASL_SSL
   ```
2. Configure a service name that matches the primary name of the Kafka server configured in the broker JAAS file.
   ```bash
   sasl.kerberos.service.name=kafka
   ```
3. Configure the JAAS configuration property with a unique principal, i.e., usually the same name as the user running the client, and keytab, i.e., secret key, for each client.
   ```bash
   sasl.jaas.config=com.sun.security.auth.module.Krb5LoginModule required \
       useKeyTab=true \
       storeKey=true \
       keyTab="/etc/security/keytabs/kafka_client.keytab" \
       principal="kafkaclient1@EXAMPLE.COM";
   ```
4. For command-line utilities like `kafka-console-consumer` or `kafka-console-producer`, `kinit` can be used along with `useTicketCache=true`.
   ```bash
   sasl.jaas.config=com.sun.security.auth.module.Krb5LoginModule required \
       useTicketCache=true;
   ```

<a id="sasl-gssapi-connect-workers"></a>

### Kafka Connect

This section describes how to enable security for Kafka Connect. Securing Kafka Connect requires that you configure security for:

1. Kafka Connect workers: part of the Kafka Connect API, a worker is really just an advanced client, underneath the covers
2. Kafka Connect connectors: connectors may have embedded producers or consumers, so you must override the default configurations for Connect producers used with source connectors and Connect consumers used with sink connectors
3. Kafka Connect REST: Kafka Connect exposes a REST API that can be configured to use TLS/SSL using [additional properties](../../../protect-data/encrypt-tls.md#encryption-ssl-rest)

Configure security for Kafka Connect as described in the section below. Additionally, if you are using Confluent Control Center streams monitoring for Kafka Connect, configure security for:

* [Confluent Metrics Reporter](#sasl-gssapi-metrics-reporter)

Configure all the following properties in `connect-distributed.properties`.

1. Configure the Connect workers to use SASL/GSSAPI.
   ```bash
   sasl.mechanism=GSSAPI
   sasl.kerberos.service.name=kafka
   # Configure SASL_SSL if TLS/SSL encryption is enabled, otherwise configure SASL_PLAINTEXT
   security.protocol=SASL_SSL
   ```
2. Configure the JAAS configuration property with a unique principal, i.e., usually the same name as the user running the worker, and keytab, i.e., secret key, for each worker.
   ```bash
   sasl.jaas.config=com.sun.security.auth.module.Krb5LoginModule required \
      useKeyTab=true \
      storeKey=true \
      keyTab="/etc/security/keytabs/kafka_client.keytab" \
      principal="connect@EXAMPLE.COM";
   ```
3. For the connectors to leverage security, you also have to override the default producer/consumer configuration that the worker uses. Depending on whether the connector is a source or sink connector:
   * Source connector: configure the same properties adding the `producer` prefix.
     ```bash
     producer.sasl.mechanism=GSSAPI
     producer.sasl.kerberos.service.name=kafka
     # Configure SASL_SSL if TLS/SSL encryption is enabled, otherwise configure SASL_PLAINTEXT
     producer.security.protocol=SASL_SSL
     producer.sasl.jaas.config=com.sun.security.auth.module.Krb5LoginModule required \
        useKeyTab=true \
        storeKey=true \
        keyTab="/etc/security/keytabs/kafka_client.keytab" \
        principal="connect@EXAMPLE.COM";
     ```
   * Sink connector: configure the same properties adding the `consumer` prefix.
     ```bash
     consumer.sasl.mechanism=GSSAPI
     consumer.sasl.kerberos.service.name=kafka
     # Configure SASL_SSL if TLS/SSL encryption is enabled, otherwise configure SASL_PLAINTEXT
     consumer.security.protocol=SASL_SSL
     consumer.sasl.jaas.config=com.sun.security.auth.module.Krb5LoginModule required \
        useKeyTab=true \
        storeKey=true \
        keyTab="/etc/security/keytabs/kafka_client.keytab" \
        principal="connect@EXAMPLE.COM";
     ```

<a id="sasl-gssapi-replicator"></a>

### Confluent Replicator

Confluent Replicator is a type of Kafka source connector that replicates data from a source to destination Kafka cluster. An embedded consumer inside Replicator consumes data from the source cluster, and an embedded producer inside the Kafka Connect worker produces data to the destination cluster.

Replicator version 4.0 and earlier requires a connection to ZooKeeper in the origin and destination Kafka clusters. If ZooKeeper is configured for authentication, the client configures the ZooKeeper security credentials via the global JAAS configuration setting `-Djava.security.auth.login.config` on the Connect workers, and the ZooKeeper security credentials in the origin and destination clusters must be the same.

To configure Confluent Replicator security, you must configure the Replicator connector as shown below and additionally you must configure:

* [Kafka Connect](#sasl-gssapi-connect-workers)

Configure Confluent Replicator to use SASL/GSSAPI by adding these properties in the Replicator’s JSON configuration file.

```bash
{
  "name":"replicator",
    "config":{
      ....
      "src.kafka.security.protocol" : "SASL_SSL",
      "src.kafka.sasl.mechanism" : "GSSAPI",
      "src.kafka.sasl.kerberos.service.name" : "kafka",
      "src.kafka.sasl.jaas.config" : "com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true storeKey=true keyTab=\"/etc/security/keytabs/kafka_client.keytab\" principal=\"replicator@EXAMPLE.COM\";",
      ....
    }
  }
}
```

#### SEE ALSO
To see an example Confluent Replicator configuration, see the [SASL source authentication demo script](https://github.com/confluentinc/examples/tree/latest//replicator-security/scripts/submit_replicator_source_sasl_plain_auth.sh). For demos of common security configurations see: [Replicator security demos](https://github.com/confluentinc/examples/tree/latest//replicator-security)

To configure Confluent Replicator for a destination cluster with SASL/GSSAPI authentication, modify the Replicator JSON configuration to include the following:

```bash
{
  "name":"replicator",
    "config":{
      ....
      "dest.kafka.security.protocol" : "SASL_SSL",
      "dest.kafka.sasl.mechanism" : "GSSAPI",
      "dest.kafka.sasl.kerberos.service.name" : "kafka",
      "dest.kafka.sasl.jaas.config" : "com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true storeKey=true keyTab=\"/etc/security/keytabs/kafka_client.keytab\" principal=\"replicator@EXAMPLE.COM\";",
      ....
    }
  }
}
```

Additionally, you can configure the following properties on the Connect worker:

```bash
sasl.mechanism=GSSAPI
security.protocol=SASL_SSL
sasl.jaas.config=com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true storeKey=true keyTab="/etc/security/keytabs/kafka_client.keytab" principal="replicator@EXAMPLE.COM";
sasl.kerberos.service.name=kafka
producer.sasl.mechanism=GSSAPI
producer.security.protocol=SASL_SSL
producer.sasl.jaas.config=com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true storeKey=true keyTab="/etc/security/keytabs/kafka_client.keytab" principal="replicator@EXAMPLE.COM";
producer.sasl.kerberos.service.name=kafka
```

For more information, see the general security configuration for Connect workers in [Kafka Connect Security Basics for Confluent Platform](../../../../connect/security.md#connect-security), and [Replicator Security Overview](../../../../multi-dc-deployments/replicator/index.md#replicator-security-overview).

#### SEE ALSO
To see an example Confluent Replicator configuration, see the [SASL destination authentication demo script](https://github.com/confluentinc/examples/tree/latest//replicator-security/scripts/submit_replicator_dest_sasl_plain_auth.sh). For demos of common security configurations see: [Replicator security demos](https://github.com/confluentinc/examples/tree/latest//replicator-security)

### Confluent Control Center

Confluent Control Center uses Kafka Streams as a state store, so if all the Kafka brokers in the cluster backing Control Center are secured, then the Control Center application also needs to be secured.

#### NOTE
When [RBAC](/control-center/current/security/c3-rbac.html) is enabled, Control Center
cannot be used in conjunction with Kerberos because Control Center cannot
support any SASL mechanism other than OAUTHBEARER.

Enable security for the Control Center application as described in the section below. Additionally, configure security for the following components:

* Confluent Metrics Reporter <sasl_gssapi_metrics-reporter>: required on the production cluster being monitored

1. Enable SASL/GSSAPI and the security protocol for Control Center in the
   `etc/confluent-control-center/control-center.properties` file.
   ```bash
   confluent.controlcenter.streams.sasl.mechanism=GSSAPI
   # Configure SASL_SSL if TLS/SSL encryption is enabled, otherwise configure SASL_PLAINTEXT
   confluent.controlcenter.streams.security.protocol=SASL_SSL
   ```
2. Since you are using GSSAPI, configure a Kerberos service name that matches
   the primary name of the Kafka server configured in the broker JAAS file.
   ```bash
   confluent.controlcenter.streams.sasl.kerberos.service.name=kafka
   ```
3. Configure the JAAS configuration property with a unique principal, which is
   usually the same Control Center name as the user running Control Center, and a keytab (secret key).
   ```bash
   confluent.controlcenter.streams.sasl.jaas.config=com.sun.security.auth.module.Krb5LoginModule required \
    useKeyTab=true \
    storeKey=true \
    keyTab="/etc/security/keytabs/kafka_client.keytab" \
    principal="controlcenter@EXAMPLE.COM";
   ```

<a id="sasl-gssapi-metrics-reporter"></a>

### Confluent Metrics Reporter

This section describes how to configure your brokers to enable security for Confluent Metrics Reporter, which is used for Confluent Control Center and Auto Data Balancer.

To configure the Confluent Metrics Reporter for SASL/GSSAPI, make the following configuration changes in the `server.properties` file in every broker in the production cluster being monitored.

1. Verify that the Confluent Metrics Reporter is enabled.
   ```bash
   metric.reporters=io.confluent.metrics.reporter.ConfluentMetricsReporter
   confluent.metrics.reporter.bootstrap.servers=kafka1:9093
   ```
2. Enable the SASL/GSSAPI mechanism for Confluent Metrics Reporter.
   ```bash
   confluent.metrics.reporter.sasl.mechanism=GSSAPI
   # Configure SASL_SSL if TLS/SSL encryption is enabled, otherwise configure SASL_PLAINTEXT
   confluent.metrics.reporter.security.protocol=SASL_SSL
   ```
3. Since you are using GSSAPI, configure a Kerberos service name that matches the primary name of the Kafka server configured in the broker JAAS file.
   ```bash
   confluent.metrics.reporter.sasl.kerberos.service.name=kafka
   ```
4. Configure the JAAS configuration property with a unique principal and keytab, i.e., secret key.
   ```bash
   confluent.metrics.reporter.sasl.jaas.config=com.sun.security.auth.module.Krb5LoginModule required \
      useKeyTab=true \
      storeKey=true \
      keyTab="/etc/security/keytabs/kafka_client.keytab" \
      principal="client@EXAMPLE.COM";
   ```

### Schema Registry

Schema Registry uses Kafka to persist schemas, and so it acts as a client to write data to the Kafka cluster. Therefore, if the Kafka brokers are configured for security, you should also configure Schema Registry to use security.  You may also refer to the complete list of [Schema Registry configuration options](../../../../schema-registry/installation/config.md#schemaregistry-config).

1. Here is an example subset of `schema-registry.properties` configuration parameters to add for SASL authentication:
   ```bash
   kafkastore.bootstrap.servers=kafka1:9093
   # Configure SASL_SSL if TLS/SSL encryption is enabled, otherwise configure SASL_PLAINTEXT
   kafkastore.security.protocol=SASL_SSL
   kafkastore.sasl.mechanism=GSSAPI
   ```
2. Since you are using GSSAPI, configure a service name that matches the primary name of the Kafka server configured in the broker JAAS file.
   ```bash
   kafkastore.sasl.kerberos.service.name=kafka
   ```
3. Configure the JAAS configuration property with a unique principal, i.e., usually the same name as the user running Schema Registry, and keytab, i.e., secret key.
   ```bash
   kafkastore.sasl.jaas.config=com.sun.security.auth.module.Krb5LoginModule required \
      useKeyTab=true \
      storeKey=true \
      keyTab="/etc/security/keytabs/kafka_client.keytab" \
      principal="schemaregistry@EXAMPLE.COM";
   ```

### REST Proxy

Securing Confluent REST Proxy for SASL requires that you configure security between
the REST proxy and the Confluent Platform cluster.

For a complete list of all configuration options, refer to [SASL Authentication](../../../../kafka-rest/production-deployment/rest-proxy/security.md#kafka-rest-security-kafka-auth-sasl).

1. Here is an example subset of `kafka-rest.properties` configuration parameters to add for SASL/GSSAPI authentication
   ```bash
   client.bootstrap.servers=kafka1:9093
   client.sasl.mechanism=GSSAPI
   # Configure SASL_SSL if TLS/SSL encryption is enabled, otherwise configure SASL_PLAINTEXT
   client.security.protocol=SASL_SSL
   ```
2. Configure a service name that matches the primary name of the Kafka server configured in the broker JAAS file.
   ```bash
   client.sasl.kerberos.service.name=kafka
   ```
3. Configure the JAAS configuration property with a unique principal, i.e., usually the same name as the user running the REST Proxy, and keytab, i.e., secret key.
   ```bash
   client.sasl.jaas.config=com.sun.security.auth.module.Krb5LoginModule required \
      useKeyTab=true \
      storeKey=true \
      keyTab="/etc/security/keytabs/kafka_client.keytab" \
      principal="restproxy@EXAMPLE.COM";
   ```

<a id="rebalancer-sasl-config"></a>

### Confluent Rebalancer

To secure Confluent Rebalancer for SASL, specify the
[metrics configuration options](../../../../clusters/rebalancer/configuration-options.md#rebalancer-config-options) for the Confluent Platform cluster
in the `rebalance-metrics-client.properties` file (or a file name of your choosing):

```bash
confluent.rebalancer.metrics.security.protocol=SASL_SSL
confluent.rebalancer.metrics.sasl.mechanism=GSSAPI
confluent.rebalancer.metrics.sasl.kerberos.service.name=kafka
confluent.rebalancer.metrics.ssl.truststore.location=<path>/kafka.client.truststore.jks
confluent.rebalancer.metrics.ssl.truststore.password=<truststore-password>
confluent.rebalancer.metrics.sasl.jaas.config= com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true storeKey=true keyTab="<path/>kafka.user.keytab" principal="kafka@KAFKA.SECURE";
confluent.rebalancer.metrics.ssl.keystore.location=<path>/kafka.server.keystore.com.jks
confluent.rebalancer.metrics.ssl.keystore.password=<keystore-password>
confluent.rebalancer.metrics.ssl.key.password=<key-password>
```

Then pass the configuration in `rebalance-metrics-client.properties` at the `confluent-rebalancer` command
line. For example:

```none
confluent-rebalancer execute --bootstrap-server <localhost>:9092 --config-file rebalance-metrics-client.properties --command-config rebalance-admin-client.properties --throttle 100000 --verbose
```

Note that the `--config-file` option specifies connectivity to the metrics cluster,
and that the `--command-config` option specifies the admin client’s connectivity to the
cluster being rebalanced. To ensure a secure connection when specifying connectivity
for the admin client (`rebalance-admin-client.properties`) use the same security
configuration as used for `rebalance-metrics-client.properties`, except you
do not need to include the `confluent.rebalancer.metrics.` prefix for the keys.

Also, if you need to identify a metrics cluster that is
different from the one being rebalanced, you can use the `--metrics-bootstrap-server`
option. By default, metrics are retrieved from the cluster specified in the `--bootstrap-server`
option.

You can also specify `confluent.rebalancer.metrics.sasl.jaas.config` by passing
the JAAS configuration file location as a JVM parameter, as shown here:

```none
export REBALANCER_OPTS="-Djava.security.auth.login.config=<path-to-jaas.conf>"
```

### JNDI Allowlist for SASL JAAS Configuration

To enhance security, especially when your `sasl.jaas.config` includes JNDI
lookups (for example, for LDAP authentication), define the
`sasl.jaas.config.jndi.allowlist` system property. This property restricts
which JNDI properties can be configured in your SASL JAAS configuration,
mitigating potential JNDI injection vulnerabilities. Set the property value
to a comma-separated list of JNDI properties.

By default, all properties prefixed with `java.naming` are denied. Only allow
trusted JNDI properties. To use any of the `java.naming` JNDI properties, you
must explicitly set `sasl.jaas.config.jndi.allowlist` to allow them. You can
use this system property as part of your `REBALANCER_OPTS`. The example below
allows the `java.naming.factory.initial` and `java.naming.provider.url`
properties:

```bash
export REBALANCER_OPTS="-Djava.security.auth.login.config=<path-to-jaas.conf> -Dsasl.jaas.config.jndi.allowlist=java.naming.factory.initial,java.naming.provider.url"
```

Alternatively, if you are not using a separate JAAS configuration file, you can set:

```bash
export REBALANCER_OPTS="-Dsasl.jaas.config.jndi.allowlist=java.naming.factory.initial,java.naming.provider.url"
```

After setting this value, validate that your configuration only allows trusted
JNDI properties. For more details, refer to [CVE-2023-25194](https://kafka.apache.org/cve-list#CVE-2023-25194).

<a id="sasl-gssapi-troubleshooting"></a>

### Troubleshooting SASL/GSSAPI

This section provides basic troubleshooting tips to address common errors that
can occur when configuring SASL/GSSAPI.

<a id="sasl-gssapi-kerberos-troubleshoot"></a>

#### Kerberos

The following hostname error may appear in your service logs when hostnames and
principals in Kerberos hosts do not match exactly:

```text
org.apache.kafka.common.errors.SaslAuthenticationException: An error: (java.security.PrivilegedActionException: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Server not found in Kerberos database (7))]) occurred when evaluating SASL token received from the Kafka Broker. This may be caused by Java's being unable to resolve the Kafka Broker's hostname correctly. You may want to try to adding '-Dsun.net.spi.nameservice.provider.1=dns,sun' to your client's JVMFLAGS environment. Users must configure FQDN of kafka brokers when authenticating using SASL and `socketChannel.socket().getInetAddress().getHostName()` must match the hostname in `principal/hostname@realm` Kafka Client will go to AUTHENTICATION_FAILED state.
Caused by: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Server not found in Kerberos database (7))]
      at com.sun.security.sasl.gsskerb.GssKrb5Client.evaluateChallenge(GssKrb5Client.java:211)
  ...
Caused by: GSSException: No valid credentials provided (Mechanism level: Server not found in Kerberos database (7))
      ... 26 more
```

To avoid such hostname errors:

- Ensure that the value specified for `sasl.kerberos.service.name` in the
  properties file matches the primary name in the corresponding keytab file. For
  example, if `principal="kafka_broker/kafka1.hostname.com@EXAMPLE.COM"`, then
  the primary is `kafka_broker`, so you must configure
  `sasl.kerberos.service.name=kafka_broker`.
- Verify that the `kinit`, `klist`, and `kdestroy` commands work as expected
  to initialize, list, and delete Kerberos credentials using the keytab. For
  example:
  ```text
  # To display the current contents of the cache
  klist
  # To acquire new credentials
  kinit -k -t ./filename.keytab kafka_broker/kafka1.hostname.com@EXAMPLE.COM
  # To verify that the credentials were initialized and updated
  klist
  # To remove any newly-initialized credentials (if necessary)
  kdestroy
  ```
- Verify that the Kerberos environment is set up correctly between clients and
  servers. For more information, see
  [Exercise 4: Using the Oracle Java SASL API](https://docs.oracle.com/javase/8/docs/technotes/guides/security/jgss/lab/part2.html)
  for a simple Kerberos-based `SaslTestClient` and `SaslServer` application
  that uses the Java SASL API to verify communications between client and server
  hosts.

<a id="sasl-gssapi-keytab-rotation"></a>

#### Keytab rotation best practices

Rotating keytabs periodically is a Kerberos security best practice, but it requires
care to avoid disrupting Kafka broker authentication. Because Kafka uses long-lived
SASL connections, some brief disruption may occur during rotation.
Follow these practices to minimize the risk:

1. **Merge new keys into the existing keytab** instead of replacing it. This preserves
   both the old and new key version numbers (KVNOs) in the keytab file during the
   transition, allowing active connections to continue authenticating while new
   connections use the updated keys:
   ```bash
   # Add new keys to the existing keytab without removing old entries
   sudo /usr/sbin/kadmin.local -q "ktadd -norandkey -k /etc/security/keytabs/{keytabname}.keytab kafka/{hostname}@{REALM}"
   ```
2. **Verify KVNO consistency** between the key distribution center (KDC) and the
   keytab file after rotation. A KVNO mismatch is the most common cause of
   authentication failures following a keytab rotation:
   ```bash
   # Check the KVNO for a principal registered in the KDC
   kvno kafka/{hostname}@{REALM}
   # List the keys and KVNOs stored in the keytab file
   klist -kte /etc/security/keytabs/{keytabname}.keytab
   ```

   The KVNO reported by `kvno` and the highest KVNO shown by `klist -kte` for
   the same principal must match. If they do not match, re-export the keytab from
   the KDC.
3. **Monitor broker logs after rotation** to confirm that clients re-authenticate
   successfully. Look for `[SASL server successful]` log entries and verify that
   no `SaslAuthenticationException` errors appear during the rotation process.

#### LDAP

To test and troubleshoot your LDAP configuration when configuring Confluent Platform to
authenticate to LDAP using Kerberos, refer to [Testing and Troubleshooting LDAP Client Authentication](../../ldap/client-authentication-ldap.md#test-ldap-client-authentication).
