Cassandra Encryption

Cassandra supports two types of encryption: encryption in transit (TLS/SSL for client-to-node and node-to-node communication) and encryption at rest (encrypting data files on disk). Together they protect sensitive data from interception and unauthorized disk access.

Encryption in Transit

Without encryption in transit, data travelling between your application and Cassandra — and between Cassandra nodes — travels in plain text over the network. Anyone with access to the network can read credentials, query results, and data. TLS encrypts all network communication.

Two TLS Scopes

Scope                Description
──────────────────────────────────────────────────────────────
Client-to-Node TLS   Encrypts traffic between your application
                     (or cqlsh) and the Cassandra node
Node-to-Node TLS     Encrypts inter-node gossip and data
                     streaming traffic inside the cluster

Generating Certificates

TLS requires a certificate authority (CA), server certificates, and optionally client certificates for mutual TLS (mTLS). The example below uses a self-signed CA for a development setup. In production, use certificates from an internal CA or a trusted certificate authority.

# Generate a CA private key and certificate:
openssl genrsa -out ca.key 4096
openssl req -new -x509 -key ca.key -out ca.crt -days 3650 \
  -subj "/CN=Cassandra CA"

# Generate a server key and certificate signing request:
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr \
  -subj "/CN=cassandra-node1"

# Sign the server certificate with the CA:
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \
  -CAcreateserial -out server.crt -days 365

# Create a PKCS12 keystore for Cassandra (Java requires this):
openssl pkcs12 -export -in server.crt -inkey server.key \
  -out server.p12 -name cassandra -password pass:cassandra

# Convert to JKS (Java KeyStore):
keytool -importkeystore -srckeystore server.p12 -srcstoretype PKCS12 \
  -destkeystore server.jks -deststoretype JKS \
  -srcstorepass cassandra -deststorepass cassandra

# Import CA into truststore:
keytool -importcert -alias CARoot -file ca.crt \
  -keystore truststore.jks -storepass cassandra -noprompt

Enabling Client-to-Node TLS

# cassandra.yaml
client_encryption_options:
  enabled: true
  optional: false              # set false to require TLS (no plain-text)
  keystore: /etc/cassandra/ssl/server.jks
  keystore_password: cassandra
  truststore: /etc/cassandra/ssl/truststore.jks
  truststore_password: cassandra
  require_client_auth: false   # set true for mutual TLS

Enabling Node-to-Node TLS

# cassandra.yaml
server_encryption_options:
  internode_encryption: all    # options: none, dc, rack, all
  keystore: /etc/cassandra/ssl/server.jks
  keystore_password: cassandra
  truststore: /etc/cassandra/ssl/truststore.jks
  truststore_password: cassandra
  require_client_auth: true    # nodes authenticate each other

internode_encryption Options

Value    Encrypts
──────────────────────────────────────────────────────────────
none     Nothing (default, insecure)
dc       Only cross-datacenter traffic
rack     Cross-rack traffic within a DC
all      All internode traffic (most secure)

Connecting cqlsh with TLS

cqlsh --ssl \
  --ssl-certfile /etc/cassandra/ssl/ca.crt \
  --ssl-userkey /path/to/client.key \
  --ssl-usercert /path/to/client.crt \
  -u alice -p 'Al1ce$ecure!' \
  10.0.0.1 9042

Connecting Java Driver with TLS

SSLContext sslContext = SSLContext.getInstance("TLS");
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(new FileInputStream("truststore.jks"), "cassandra".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(
    TrustManagerFactory.getDefaultAlgorithm());
tmf.init(trustStore);
sslContext.init(null, tmf.getTrustManagers(), null);

CqlSession session = CqlSession.builder()
  .withSslContext(sslContext)
  .addContactPoint(new InetSocketAddress("10.0.0.1", 9042))
  .withAuthCredentials("alice", "Al1ce$ecure!")
  .withLocalDatacenter("us-east")
  .build();

Encryption at Rest

Encryption at rest protects SSTable files on disk from unauthorized physical access. Even if a disk is stolen or a snapshot is extracted, the data remains unreadable without the encryption key.

Transparent Data Encryption (TDE)

Cassandra supports transparent data encryption of SSTables using a configurable encryption provider. The configuration lives in cassandra.yaml.

# cassandra.yaml (encryption at rest example)
transparent_data_encryption_options:
  enabled: true
  chunk_length_kb: 64
  cipher: AES/CBC/PKCS5Padding
  key_alias: cassandra_key
  key_provider:
    - class_name: org.apache.cassandra.security.JKSKeyProvider
      parameters:
        - keystore: /etc/cassandra/ssl/keystore.jks
          keystore_password: cassandra
          store_type: JCEKS
          key_password: cassandra

Audit Logging

Cassandra 4.0 introduced built-in audit logging. Audit logs record every CQL statement executed along with the user, source IP, timestamp, and keyspace. This helps detect unauthorized access and satisfy compliance requirements.

# cassandra.yaml
audit_logging_options:
  enabled: true
  logger:
    - class_name: BinAuditLogger
  included_categories: AUTH,DCL,DDL,DML,QUERY
  audit_logs_dir: /var/log/cassandra/audit/

TLS Checklist for Production

✓ Generate certificates from a trusted CA (not self-signed)
✓ Enable client_encryption_options with optional: false
✓ Enable server_encryption_options with internode_encryption: all
✓ Rotate certificates before expiry (set calendar reminders)
✓ Store keystore passwords in a secrets manager, not plain text
✓ Enable audit logging for compliance workloads
✓ Enable encryption at rest for sensitive data columns/keyspaces

Summary

Cassandra encryption covers two surfaces: data in transit (TLS) and data at rest. Enable client-to-node TLS to protect application traffic and node-to-node TLS to protect inter-cluster communication. Use certificates signed by a trusted CA in production and store keystore passwords in a secrets manager. Enable transparent data encryption for SSTables when regulatory requirements demand it. Pair encryption with authentication and authorization to build a complete security posture for your Cassandra cluster.

Leave a Comment

Your email address will not be published. Required fields are marked *