Skip to content
Maintained by AxonOps — production-grade documentation from engineers who operate distributed databases at scale

Client TLS Configuration

This section covers TLS configuration for Cassandra clients including cqlsh, Java driver, Python driver, and other language drivers.

cqlsh Configuration

Command Line Options

# Basic SSL connection
cqlsh --ssl hostname

# With explicit CA certificate
cqlsh --ssl --ssl-certfile=/path/to/ca-cert.pem hostname

# With client certificate (mutual TLS)
cqlsh --ssl \
    --ssl-certfile=/path/to/ca-cert.pem \
    --ssl-keyfile=/path/to/client-key.pem \
    --ssl-usercert=/path/to/client-cert.pem \
    hostname

cqlshrc Configuration

Create ~/.cassandra/cqlshrc:

[connection]
hostname = cassandra-node-1.example.com
port = 9042

[ssl]
# Enable SSL
certfile = /path/to/ca-cert.pem

# Validate server certificate
validate = true

# Client certificate (for mutual TLS)
userkey = /path/to/client-key.pem
usercert = /path/to/client-cert.pem

# TLS version
version = TLSv1_2

cqlshrc with Authentication

[authentication]
username = app_user
password = app_password

[connection]
hostname = cassandra-node-1.example.com
port = 9042

[ssl]
certfile = /path/to/ca-cert.pem
validate = true

Environment Variables

# Set SSL certificate path
export SSL_CERTFILE=/path/to/ca-cert.pem

# Use with cqlsh
cqlsh --ssl hostname

Java Driver Configuration

DataStax Java Driver 4.x

Programmatic Configuration

import com.datastax.oss.driver.api.core.CqlSession;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.io.FileInputStream;
import java.security.KeyStore;

public class CassandraClient {

    public static CqlSession createSecureSession() throws Exception {
        // Load truststore
        KeyStore trustStore = KeyStore.getInstance("JKS");
        trustStore.load(
            new FileInputStream("/path/to/truststore.jks"),
            "truststore_password".toCharArray()
        );

        TrustManagerFactory tmf = TrustManagerFactory
            .getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(trustStore);

        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, tmf.getTrustManagers(), null);

        return CqlSession.builder()
            .addContactPoint(new InetSocketAddress("cassandra-node-1.example.com", 9042))
            .withLocalDatacenter("dc1")
            .withSslContext(sslContext)
            .withAuthCredentials("username", "password")
            .build();
    }
}

Mutual TLS Configuration

public static CqlSession createMtlsSession() throws Exception {
    // Load keystore (client certificate)
    KeyStore keyStore = KeyStore.getInstance("PKCS12");
    keyStore.load(
        new FileInputStream("/path/to/client-keystore.p12"),
        "keystore_password".toCharArray()
    );

    KeyManagerFactory kmf = KeyManagerFactory
        .getInstance(KeyManagerFactory.getDefaultAlgorithm());
    kmf.init(keyStore, "keystore_password".toCharArray());

    // Load truststore
    KeyStore trustStore = KeyStore.getInstance("JKS");
    trustStore.load(
        new FileInputStream("/path/to/truststore.jks"),
        "truststore_password".toCharArray()
    );

    TrustManagerFactory tmf = TrustManagerFactory
        .getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(trustStore);

    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

    return CqlSession.builder()
        .addContactPoint(new InetSocketAddress("cassandra-node-1.example.com", 9042))
        .withLocalDatacenter("dc1")
        .withSslContext(sslContext)
        .build();
}

File-Based Configuration (application.conf)

datastax-java-driver {
    basic {
        contact-points = ["cassandra-node-1.example.com:9042"]
        load-balancing-policy.local-datacenter = dc1
    }

    advanced.ssl-engine-factory {
        class = DefaultSslEngineFactory

        # Truststore for server certificate validation
        truststore-path = /path/to/truststore.jks
        truststore-password = truststore_password

        # Keystore for client certificate (mutual TLS)
        keystore-path = /path/to/client-keystore.p12
        keystore-password = keystore_password

        # Hostname verification
        hostname-validation = true

        # Cipher suites
        cipher-suites = [
            "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
            "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
        ]
    }

    advanced.auth-provider {
        class = PlainTextAuthProvider
        username = app_user
        password = app_password
    }
}

DataStax Java Driver 3.x (Legacy)

import com.datastax.driver.core.Cluster;
import com.datastax.driver.core.SSLOptions;
import com.datastax.driver.core.RemoteEndpointAwareJdkSSLOptions;

Cluster cluster = Cluster.builder()
    .addContactPoint("cassandra-node-1.example.com")
    .withSSL(RemoteEndpointAwareJdkSSLOptions.builder()
        .withSSLContext(sslContext)
        .build())
    .withCredentials("username", "password")
    .build();

Python Driver Configuration

Basic SSL Connection

from cassandra.cluster import Cluster
from cassandra.auth import PlainTextAuthProvider
from ssl import SSLContext, PROTOCOL_TLS_CLIENT, CERT_REQUIRED

# Create SSL context
ssl_context = SSLContext(PROTOCOL_TLS_CLIENT)
ssl_context.verify_mode = CERT_REQUIRED
ssl_context.load_verify_locations('/path/to/ca-cert.pem')

# Create auth provider
auth_provider = PlainTextAuthProvider(
    username='app_user',
    password='app_password'
)

# Connect with SSL
cluster = Cluster(
    ['cassandra-node-1.example.com'],
    port=9042,
    ssl_context=ssl_context,
    auth_provider=auth_provider
)

session = cluster.connect()

Mutual TLS Configuration

from cassandra.cluster import Cluster
from cassandra.auth import PlainTextAuthProvider
from ssl import SSLContext, PROTOCOL_TLS_CLIENT, CERT_REQUIRED

# Create SSL context with client certificate
ssl_context = SSLContext(PROTOCOL_TLS_CLIENT)
ssl_context.verify_mode = CERT_REQUIRED
ssl_context.load_verify_locations('/path/to/ca-cert.pem')
ssl_context.load_cert_chain(
    certfile='/path/to/client-cert.pem',
    keyfile='/path/to/client-key.pem',
    password='key_password'  # If key is encrypted
)

cluster = Cluster(
    ['cassandra-node-1.example.com'],
    ssl_context=ssl_context,
    auth_provider=PlainTextAuthProvider('user', 'pass')
)

Hostname Verification

from ssl import SSLContext, PROTOCOL_TLS_CLIENT, CERT_REQUIRED
import ssl

ssl_context = SSLContext(PROTOCOL_TLS_CLIENT)
ssl_context.verify_mode = CERT_REQUIRED
ssl_context.check_hostname = True  # Enable hostname verification
ssl_context.load_verify_locations('/path/to/ca-cert.pem')

Node.js Driver Configuration

Basic SSL Connection

const cassandra = require('cassandra-driver');
const fs = require('fs');

const client = new cassandra.Client({
    contactPoints: ['cassandra-node-1.example.com'],
    localDataCenter: 'dc1',
    sslOptions: {
        ca: [fs.readFileSync('/path/to/ca-cert.pem')],
        rejectUnauthorized: true
    },
    credentials: {
        username: 'app_user',
        password: 'app_password'
    }
});

client.connect()
    .then(() => console.log('Connected'))
    .catch(err => console.error('Connection error', err));

Mutual TLS Configuration

const cassandra = require('cassandra-driver');
const fs = require('fs');

const client = new cassandra.Client({
    contactPoints: ['cassandra-node-1.example.com'],
    localDataCenter: 'dc1',
    sslOptions: {
        ca: [fs.readFileSync('/path/to/ca-cert.pem')],
        cert: fs.readFileSync('/path/to/client-cert.pem'),
        key: fs.readFileSync('/path/to/client-key.pem'),
        rejectUnauthorized: true
    }
});

Go Driver Configuration (gocql)

Basic SSL Connection

package main

import (
    "crypto/tls"
    "crypto/x509"
    "io/ioutil"
    "log"

    "github.com/gocql/gocql"
)

func main() {
    // Load CA certificate
    caCert, err := ioutil.ReadFile("/path/to/ca-cert.pem")
    if err != nil {
        log.Fatal(err)
    }

    caCertPool := x509.NewCertPool()
    caCertPool.AppendCertsFromPEM(caCert)

    // Configure TLS
    tlsConfig := &tls.Config{
        RootCAs:    caCertPool,
        MinVersion: tls.VersionTLS12,
    }

    // Create cluster config
    cluster := gocql.NewCluster("cassandra-node-1.example.com")
    cluster.SslOpts = &gocql.SslOptions{
        Config: tlsConfig,
        EnableHostVerification: true,
    }
    cluster.Authenticator = gocql.PasswordAuthenticator{
        Username: "app_user",
        Password: "app_password",
    }

    session, err := cluster.CreateSession()
    if err != nil {
        log.Fatal(err)
    }
    defer session.Close()
}

Mutual TLS Configuration

// Load client certificate and key
cert, err := tls.LoadX509KeyPair(
    "/path/to/client-cert.pem",
    "/path/to/client-key.pem",
)
if err != nil {
    log.Fatal(err)
}

tlsConfig := &tls.Config{
    RootCAs:      caCertPool,
    Certificates: []tls.Certificate{cert},
    MinVersion:   tls.VersionTLS12,
}

Connection Testing

Test with OpenSSL

# Test TLS connection to Cassandra
openssl s_client -connect cassandra-node-1.example.com:9042 \
    -CAfile /path/to/ca-cert.pem \
    -servername cassandra-node-1.example.com

# Show certificate details
openssl s_client -connect cassandra-node-1.example.com:9042 \
    -CAfile /path/to/ca-cert.pem \
    2>/dev/null | openssl x509 -noout -text

Test with cqlsh

# Verbose connection test
cqlsh --ssl --debug cassandra-node-1.example.com