3-4
Image credit: Jennefer Zacarias

In Part-2 of this series, we explored avenues for securing data in transit and described how to configure TLS/mTLS with Apache Cassandra 4.0. In Part 3, we’ll look at how you can customize TLS/mTLS for Apache Cassandra 4.1+ to overcome the challenges with a TLS configuration.

How We Made TLS Configuration Better With 4.1

With Apache Cassandra 4.1, we enhanced the TLS/mTLS configuration to allow for specifying custom ways to build SSLContext and we provided a default implementation for backward compatibility. We introduced a new configuration, ssl_context_factory, where you can specify your custom class to build SSLContext objects required by Java/Netty SSL libraries. You can also add custom properties to it via simple key-value pairs. All of this has been achieved while retaining the ability to hot-reload the security credentials as you could before version 4.0.

To demonstrate this customization, let’s use the example of Kubernetes, the popular cloud-native solution. Kubernetes allows configuring Secrets to store sensitive data. We could potentially use K8s Secrets to store the keystore and truststore artifacts along with their respective passwords. We will assume Apache Cassandra is already running in a K8s environment.

Integration with Kubernetes Secrets

We have passwords for keystore and truststore as K8s environment variables loaded from the K8s Secrets. The keystore and truststore files are loaded by the K8s Secrets. The YAML file, below, for the pod reflects these settings. This example also keeps the hot-reloading capability of security credentials by allowing the secret named keystore/truststore-last-updatedtime. You can update the timestamp value for those secrets via a kubectl command and the implementation will hot-reload the security credentials as it would filesystem-based security credentials.

Example K8s Pod Configuration

apiVersion: v1
 kind: Pod
 metadata:
   name: my-cassandra-pod
   labels:
     app: my-cassandra-app
 spec:
   containers:
   - name: my-cassandra-app
     image: my-cassandrda-app:latest
     imagePullPolicy: Always
     env:
       - name: KEYSTORE_PASSWORD
         valueFrom:
           secretKeyRef:
             name: my-ssl-store
             key: keystore-password
       - name: TRUSTSTORE_PASSWORD
         valueFrom:
           secretKeyRef:
             name: my-ssl-store
             key: truststore-password
     volumeMounts:
     - name: my-ssl-store
       mountPath: "/etc/my-ssl-store"
       readOnly: true
   volumes:
   - name: my-ssl-store
     secret:
       secretName: my-ssl-store
       items:
         - key: cassandra_ssl_keystore
           path: keystore
         - key: keystore-last-updatedtime
           path: keystore-last-updatedtime
         - key: cassandra_ssl_truststore
           path: truststore
         - key: truststore-last-updatedtime
           path: truststore-last-updatedtime

We will use the ‘KubernetesSecretsSslContextFactory’ class from Apache Cassandra 4.1 as an example for how to customize the TLS configuration via Kubernetes Secrets as loaded by the pod definition (above).

Example Custom TLS Configuration for K8s Secrets

Here we have used the configuration for server_encryption_options, but, similarly, you can use it for the client_encryption_options:

     server_encryption_options:
       internode_encryption: none
       ssl_context_factory:
         class_name: `org.apache.cassandra.security.KubernetesSecretsSslContextFactory
         parameters:
           KEYSTORE_PASSWORD_ENV_VAR: KEYSTORE_PASSWORD
           KEYSTORE_UPDATED_TIMESTAMP_PATH: /etc/my-ssl-store/keystore-last-updatedtime
           TRUSTSTORE_PASSWORD_ENV_VAR: TRUSTSTORE_PASSWORD
           TRUSTSTORE_UPDATED_TIMESTAMP_PATH: /etc/my-ssl-store/truststore-last-updatedtime
       keystore: /etc/my-ssl-store/keystore
       truststore: /etc/my-ssl-store/truststore

And Voila! Congratulations, your Apache Cassandra server is now integrated with the Kubernetes Secrets for the TLS configuration. The example above is built on the extensible class hierarchy shown, below. You can build extensions at three different levels and use composition to offer hybrid solutions you might need.

A diagram of Apache Cassandra’s extensible class hierarchy

Future work

On top of having the ability to customize TLS configuration, the community is working on supporting other popular formats for security credentials, such as PEM (originally “Privacy Enhanced Mail”).

As the Apache Cassandra community, our goal is to provide best-in-class software and keep enhancing it as the use-cases and requirements grow and evolve over time. I hope this particular enhancement makes Cassandra operators’ life easier while supporting industry standards for data security.

Update: The original blog has been updated to correctly reflect Apache Cassandra version 4.1 for the SSL Context’s customization feature. Apache Cassandra 4.1 changes are targeted to freeze in May 2022 and released in July 2022