<a id="co-security-compliance"></a>

# Security Compliance in Confluent for Kubernetes

This topic describes the support and configuration details for the Federal
Information Processing Standard (FIPS) compliance in Confluent Platform deployed by Confluent for Kubernetes
(CFK).

## FIPS 140-2 and FIPS 140-3

The [Federal Information Processing Standard (FIPS) 140](https://csrc.nist.gov/publications/detail/fips/140/2/final) series defines the
security requirements for cryptography used in the US Federal Government
systems, including FIPS 140-2 and FIPS 140-3.

While Confluent Platform is not FIPS-certified, it provides FIPS-compliant cipher enforcement
at the component level. For background on FIPS in Confluent Platform, see
[Security compliance for Confluent Platform](https://docs.confluent.io/platform/current/security/compliance/overview.html)

CFK 3.2.0 and later extend this support so that, when the underlying
operating system, cryptographic providers, and Confluent Platform components
are configured for FIPS 140-2 or FIPS 140-3 according to the Confluent Platform security compliance documentation, CFK can deploy and manage those
clusters in a FIPS-compliant mode.

Confluent Server (Confluent Kafka), KRaft, Schema Registry, Connect, and ksqlDB can be configured
to use FIPS-compliant ciphers on their TLS connections. This requires that all TLS
enabled components use the FIPS-compliant Java KeyStore type, Bouncy Castle.
These TLS configurations also include those for the listeners, the MDS, Kafka
REST class, and schema validation.

Bouncy Castle type keystores cannot be used to configure ZooKeeper TLS.

You can use [regular keystores](co-network-encryption.md#co-certs-jks) to connect non-FIPS
compliant components to the FIPS enabled listeners.

<a id="co-fips-enabled-cfk"></a>

### Deploy CFK in the FIPS mode

1. (Optional) To [enable the validating webhooks for CFK](co-cfk-settings.md#co-enable-webhooks) in the FIPS mode, you need to provide TLS keys and
   certificates in [Java KeyStore format](co-network-encryption.md#co-certs-jks). In FIPS mode, the
   webhook server requires `truststore.jks`, `keystore.jks`,
   `jksPassword.txt`.
2. Install CFK in the FIPS mode.
   * From the Confluent Helm repository, using the Helm argument,
     `-–set fipsmode=”true”`:
     ```yaml
     helm upgrade --install confluent-operator \
       confluentinc/confluent-for-kubernetes \
       --set fipsmode=true \
       --namespace <namespace>
     ```

     For details of using a Helm argument, see [Deploy CFK with Custom Values](co-deploy-custom-values.md#co-values-file).
   * Set the following property in the configuration values file.
     ```yaml
     fipsmode: true
     ```

     For details about using the configuration file, see [Deploy CFK with Custom Values](co-deploy-custom-values.md#co-values-file).

#### NOTE
Upgrading a FIPS-enabled cluster from the ZooKeeper mode to KRaft mode is not
currently supported.

As a workaround, turn off the FIPS mode for CFK, migrate to the KRaft
mode, and turn on the FIPS mode on the CFK.

### Deploy Confluent Platform in the FIPS mode

To enable FIPS for Confluent Platform:

1. [Create a secret with the FIPS-compliant keystores and truststores](#co-fips-compliant-keystores).
2. [Reference the above secret in the component custom resources (CRs)](#co-fips-enabled-cp).

<a id="co-fips-compliant-keystores"></a>

#### Create FIPS-compliant keystores

To enable FIPS in Confluent Platform, the following keys and files are required:

* Bouncy Castle keystore (`keystore.bcfks`) and truststore
  (`truststore.bcfks`)
* JKS keystore (`keystore.jks`) and truststore (`truststore.jks`) if there
  is a TLS connection between Kafka and ZooKeeper
* JKS password (`jksPassword.txt`)

The steps in this section use the commands with example use cases. Replace the
file locations and other parameters in the examples with those for your
environment.

1. To create Bouncy Castle type keystores, download the Bouncy Castle JAR:
   ```bash
   curl https://repo1.maven.org/maven2/org/bouncycastle/bc-fips/1.0.2.3/bc-fips-1.0.2.3.jar \
     -o /tmp/bc-fips-1.0.2.3.jar
   ```
2. Create all the keystores required for deployment.
   1. Create the certificate chain as described in [Provide TLS keys and certificates in PEM format](co-network-encryption.md#co-certs-pem):
      ```bash
      cat ca.pem server.pem > server-chain.pem
      ```
   2. Create the Bouncy Castle truststore using the JAR you downloaded in Step
      #1:
      ```bash
      keytool -noprompt -keystore truststore.bcfks \
          -storetype BCFKS \
          -alias CARoot \
          -import -file ca.pem \
          -storepass password \
          -keypass password \
          -providerclass org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider \
          -providerpath /tmp/bc-fips-1.0.2.3.jar
      ```
   3. Add the server certificate and the key into a PKCS12 file:
      ```bash
      openssl pkcs12 -export \
          -in server-chain.pem \
          -inkey server-key.pem \
          -out server.p12 \
          -name localhost \
          -passout pass:mykeypassword
      ```
   4. Create the Bouncy Castle keystore out of the PKCS12 created in the
      previous step:
      ```bash
      keytool -importkeystore \
          -srckeystore keystores/server.p12 \
          -srcstoretype pkcs12 \
          -srcstorepass mykeypassword \
          -destkeystore keystore.bcfks \
          -deststorepass password \
          -destkeypass password \
          -deststoretype BCFKS \
          -providername BCFIPS \
          -providerclass org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider \
          -providerpath /tmp/bc-fips-1.0.2.3.jar
      ```
   5. Import the certificate authority (CA) into the keystore:
      ```bash
      keytool -noprompt -keystore keystore.bcfks \
          -storetype BCFKS \
          -alias CARoot \
          -import -file ca.pem \
          -storepass password \
          -keypass password \
          -providerclass org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider \
          -providerpath /tmp/bc-fips-1.0.2.3.jar
      ```
   6. Inspect the keystore contents:
      ```bash
      keytool -list -keystore keystore.bcfks \
          -storepass password -v \
          -keypass password \
          -storetype BCFKS \
          -providerclass org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider \
          -providerpath /tmp/bc-fips-1.0.2.3.jar
      ```
3. Because the TLS connection between Kafka and ZooKeeper cannot use Bouncy Castle
   keystores, you must also create a PKCS12 keystore for those connections.
   1. Create the truststore:
      ```bash
      keytool -noprompt -keystore truststore.jks \
          -storetype pkcs12 \
          -alias CARoot \
          -import -file ca.pem \
          -storepass password \
          -keypass password
      ```
   2. Create the keystore out of the PKCS12 created in the previous step:
      ```bash
      keytool -importkeystore \
          -srckeystore server.p12 \
          -srcstoretype pkcs12 \
          -srcstorepass mykeypassword \
          -deststoretype pkcs12 \
          -destkeystore keystore.jks \
          -deststorepass password \
          -destkeypass password
      ```
   3. Import the certificate authority (CA) into the keystore:
      ```bash
      keytool -noprompt -keystore keystore.jks \
          -alias CARoot \
          -storetype pkcs12 \
          -import -file ca.pem \
          -storepass password \
          -keypass password
      ```
   4. Inspect the keystore content:
      ```bash
      keytool -list -keystore keystore.jks \
          -storepass password -v \
          -keypass password
      ```
4. Create the Kubernetes secret with the keystores:
   ```bash
   kubectl create secret generic fips-tls \
       --from-file=keystore.bcfks=keystore.bcfks \
       --from-file=truststore.bcfks=truststore.bcfks \
       --from-file=keystore.jks=keystore.jks \
       --from-file=truststore.jks=truststore.jks \
       --from-literal=jksPassword.txt=jksPassword=password
   ```

<a id="co-fips-enabled-ak"></a>

<a id="co-fips-enabled-cp"></a>

#### Configure FIPS-enabled Confluent Platform

To enable FIPS for Kafka, KRaft, Schema Registry, Connect, and ksqlDB, add the
following settings in each component custom resource (CR):

```yaml
kind: <component>
spec:
  tls:
    fips:
       enabled: true   --- [1]
       mode: <fips-mode>   --- [2]       # Optional, CFK 3.2.0+
    secretRef:         --- [3]
```

* [1] `enabled` is required and turns on FIPS support for the component.
* [2] `mode` is optional and, in CFK 3.2.0 and later, controls the FIPS
  operation mode used by the component.
* [3] `secretRef` is the name of the secret created in [Create FIPS-compliant keystores](#co-fips-compliant-keystores).

For backward compatibility, the Kafka API to enable FIPS in CFK 2.5 through
2.8 (`kafka.spec.fips`) is still supported for Kafka in this release of CFK.
As a best practice, use the current API as described in the preceding section.

#### WARNING
Azure Tiered Storage is not supported on FIPS-enabled CFK deployments because
CFK does not provide Azure-specific TLS settings in FIPS mode, and the
broker JVM truststore cannot be overridden to add the Azure
storage CAs required for Azure Tiered Storage connectivity. This causes TLS
failures when configuring Tiered Storage with Azure.
