Client Encryption (SSL/TLS)
coodie supports SSL/TLS encryption for connections to Cassandra and ScyllaDB
through the underlying driver. init_coodie() and init_coodie_async() expose
first-class keyword arguments for SSL configuration so that IDEs and type
checkers surface them. Any extra keyword arguments are still forwarded to the
underlying driver for full flexibility.
CassandraDriver (scylla-driver / cassandra-driver)
SSL is configured via Python’s standard ssl.SSLContext, passed as the
ssl_context keyword argument to init_coodie().
Disable server certificate verification (development only)
import ssl
from coodie.sync import init_coodie
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE # ⚠️ do not use in production
init_coodie(
hosts=["127.0.0.1"],
keyspace="my_ks",
ssl_context=ssl_context,
)
Verify the server’s certificate against a CA (recommended)
import ssl
from coodie.sync import init_coodie
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_REQUIRED
ssl_context.load_verify_locations("/path/to/ca.crt")
init_coodie(
hosts=["node1", "node2", "node3"],
keyspace="my_ks",
ssl_context=ssl_context,
)
Mutual TLS — client certificate authentication
Some deployments require the client to present its own certificate:
import ssl
from coodie.sync import init_coodie
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_REQUIRED
ssl_context.load_verify_locations("/path/to/ca.crt")
ssl_context.load_cert_chain(
certfile="/path/to/client.crt",
keyfile="/path/to/client.key",
)
init_coodie(
hosts=["node1"],
keyspace="my_ks",
ssl_context=ssl_context,
)
Async applications
The same ssl_context keyword works with the async API:
import ssl
from coodie.aio import init_coodie
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_REQUIRED
ssl_context.load_verify_locations("/path/to/ca.crt")
await init_coodie(
hosts=["node1"],
keyspace="my_ks",
ssl_context=ssl_context,
)
Bring your own session (BYOS)
If you already have a fully configured cassandra.cluster.Cluster, pass its
session directly and coodie will use it as-is:
import ssl
from cassandra.cluster import Cluster
from coodie.sync import init_coodie
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_REQUIRED
ssl_context.load_verify_locations("/path/to/ca.crt")
cluster = Cluster(
["node1"],
ssl_context=ssl_context,
connect_timeout=30,
)
session = cluster.connect("my_ks")
init_coodie(session=session, keyspace="my_ks")
AcsyllaDriver
acsylla takes SSL configuration as keyword arguments. init_coodie_async()
(aliased as coodie.aio.init_coodie()) exposes these as first-class parameters:
Parameter |
Type |
Description |
|---|---|---|
|
|
Enable TLS for the connection |
|
|
PEM-encoded CA certificate |
|
|
PEM-encoded client certificate (mutual TLS) |
|
|
PEM-encoded client private key (mutual TLS) |
|
|
Verification flags (e.g. |
Disable certificate verification (development only)
from coodie.aio import init_coodie
await init_coodie(
hosts=["127.0.0.1"],
keyspace="my_ks",
driver_type="acsylla",
ssl_enabled=True,
ssl_verify_flags=0, # CASS_SSL_VERIFY_NONE
)
Verify the server’s certificate against a CA (recommended)
from coodie.aio import init_coodie
ca_pem = open("/path/to/ca.crt").read()
await init_coodie(
hosts=["node1", "node2"],
keyspace="my_ks",
driver_type="acsylla",
ssl_enabled=True,
ssl_trusted_cert=ca_pem,
)
Mutual TLS — client certificate authentication
from coodie.aio import init_coodie
ca_pem = open("/path/to/ca.crt").read()
client_cert_pem = open("/path/to/client.crt").read()
client_key_pem = open("/path/to/client.key").read()
await init_coodie(
hosts=["node1"],
keyspace="my_ks",
driver_type="acsylla",
ssl_enabled=True,
ssl_trusted_cert=ca_pem,
ssl_cert=client_cert_pem,
ssl_private_key=client_key_pem,
)
Bring your own session (BYOS)
Create the acsylla session yourself and pass it via session=:
import acsylla
from coodie.aio import init_coodie
ca_pem = open("/path/to/ca.crt").read()
cluster = acsylla.create_cluster(
["node1"],
ssl_enabled=True,
ssl_trusted_cert=ca_pem,
)
session = await cluster.create_session(keyspace="my_ks")
await init_coodie(
session=session,
keyspace="my_ks",
driver_type="acsylla",
)
ScyllaDB Server Configuration
To enable client-to-server encryption on the ScyllaDB side, add the following to
/etc/scylla/scylla.yaml:
client_encryption_options:
enabled: true
certificate: /path/to/server.crt
keyfile: /path/to/server.key
# Uncomment to require clients to present a certificate:
# require_client_auth: true
# truststore: /path/to/ca.crt
After editing, restart ScyllaDB:
sudo systemctl restart scylla-server
For Cassandra, edit cassandra.yaml in the same way:
client_encryption_options:
enabled: true
keystore: /path/to/server.keystore
keystore_password: changeit
Generating Self-Signed Certificates for Development
# 1 — Create a CA key and self-signed certificate
openssl genrsa -out ca.key 4096
openssl req -new -x509 -days 365 -key ca.key -out ca.crt \
-subj "/CN=Test CA"
# 2 — Create a server key and certificate signing request
openssl genrsa -out server.key 4096
openssl req -new -key server.key -out server.csr \
-subj "/CN=localhost"
# 3 — Sign the server certificate with the CA
openssl x509 -req -days 365 -in server.csr \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-out server.crt
# 4 — (Optional) Create a client key + certificate for mutual TLS
openssl genrsa -out client.key 4096
openssl req -new -key client.key -out client.csr \
-subj "/CN=coodie-client"
openssl x509 -req -days 365 -in client.csr \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-out client.crt
What’s Next?
Drivers & Initialization — driver initialization and connection options
Sync vs Async API — choosing between sync and async APIs