Chapter 26 · Security: Authentication, Authorization, Roles, TLS, and Secrets
Internode Encryption vs Client TLS: Certificates, Trust, Rotation, and Failure Modes
Protect and verify client and internode TLS independently, including certificate rotation failures.
Learning outcomes
Password authentication does not encrypt network traffic. Enabling client TLS does not encrypt gossip, repair or streaming, and it does not secure JMX. This lesson treats each path separately and rehearses certificate rotation failure modes.
Distinguish client TLS, internode TLS, JMX protection, authentication and authorization.
Generate disposable per-node certificate material without embedding private keys.
Use optional=true as a rolling migration state, then enforce TLS-only traffic.
Verify active TLS with certificate evidence and system_views.clients.
Rehearse trust/SAN/expiry/key mismatch and rotation/hot-reload behavior.
The mandatory work uses a separate disposable security cluster
so hardening experiments cannot lock the shared course
cluster. Pin Apache Cassandra 5.0.9 with the
official cassandra:5.0.9 image, Java 17 from that
image, Docker network
atlasmart-cassandra-security, cluster
atlasmart-security, nodes
atlasmart-sec-1..3, datacenter dc1,
racks rack1..rack3, 16 virtual nodes (vnodes) per
node, NetworkTopologyStrategy, replication factor
(RF) 3, and LOCAL_QUORUM for application-style
verification. Tables use UnifiedCompactionStrategy (UCS),
default_time_to_live=0, and
gc_grace_seconds=864000.
The lab intentionally starts with Cassandra's compatible
security defaults so the migration is observable:
AllowAllAuthenticator,
AllowAllAuthorizer, client TLS disabled,
internode encryption none, and JMX local-only. No
Cassandra/JMX/storage ports are published to the host. This is
a local learning boundary, not a production posture. Never
place a real password, token, private key, keystore password,
backup key, or break-glass credential into Git, lesson HTML,
screenshots, chat, shell history, or process arguments.
Run commands only against the disposable Apache Cassandra course lab or another explicitly approved non-production environment. Confirm node, keyspace, table, container, volume, path, and datacenter targets before destructive, failure-injection, cleanup, repair, restore, security, or topology operations. Capture current state and expected rollback/recovery evidence first; output and timings can differ by host, operating system, Java runtime, Docker/runtime, driver, and Cassandra configuration.
Terms before the security mechanisms
CQL is Cassandra Query Language. A coordinator is the node accepting a client request; replicas store copies of the target partition. A partition is the row group located by a partition key; its hash maps to a token. vnodes are multiple token ranges assigned per node. A keyspace defines replication. RF is replication factor and CL is consistency level. An SSTable is Cassandra's immutable on-disk table file set; compaction merges SSTables; repair compares replica ranges and streams differences. SAI is Storage-Attached Indexing. A driver is the client library speaking Cassandra's native protocol.
Authentication proves an identity; Cassandra's
authenticator implements that decision.
Authorization decides what an authenticated
identity may do; the authorizer checks
permissions on Cassandra resources. A role is
Cassandra's principal/inheritance object;
LOGIN=true makes it directly authenticatable. A
superuser bypasses normal authorization and
therefore belongs only in tightly controlled administration or
break-glass recovery. Least privilege grants
only the permissions needed.
TLS (Transport Layer Security) protects network
traffic and authenticates endpoints with certificates.
Client TLS protects application/cqlsh ↔
Cassandra native protocol;
internode TLS protects Cassandra node ↔ node
gossip/replication/streaming. mTLS (mutual TLS)
means both sides present certificates. A
keystore holds private key/certificate material
and a truststore holds trust anchors.
JMX (Java Management Extensions) is Cassandra's
management interface used by nodetool.
Defense in depth layers identity, permissions,
encryption, network isolation, secrets, backups, audit, patching
and recovery instead of trusting one control.
1. Three network planes, three controls
| Plane | Interface | Security control | What another plane does not solve |
|---|---|---|---|
| client/native | 9042 | client_encryption_options + client trust validation | internode TLS does not protect client CQL |
| internode | storage/gossip/streaming | server_encryption_options / internode_encryption | client TLS does not protect repair/streaming |
| management | JMX | local-only or JMX auth+TLS+network policy | CQL roles/TLS do not secure JMX |
Cassandra 5.0's preferred model is a single native transport
port; the older dedicated SSL port is deprecated. A rolling
migration can temporarily accept encrypted and unencrypted
traffic with optional=true, but the end state
should enforce the intended policy.
2. Generate disposable lab certificates
New-Item -ItemType Directory -Force .\ch26-tls | Out-Nullif (-not $env:ATLASMART_TLS_STORE_PASSWORD) { throw "Set the store secret from an approved source." }1..3 | ForEach-Object { $n=$_ docker run --rm -e ATLASMART_TLS_STORE_PASSWORD="$env:ATLASMART_TLS_STORE_PASSWORD" ` -v "${PWD}/ch26-tls:/tls" --entrypoint keytool cassandra:5.0.9 ` -genkeypair -alias "atlasmart-sec-$n" -keyalg RSA -keysize 2048 -validity 30 ` -dname "CN=atlasmart-sec-$n,OU=Training,O=AtlasMart,C=XX" ` -ext "SAN=dns:atlasmart-sec-$n" -keystore "/tls/node$n.p12" -storetype PKCS12 ` -storepass:env ATLASMART_TLS_STORE_PASSWORD -keypass:env ATLASMART_TLS_STORE_PASSWORD docker run --rm -e ATLASMART_TLS_STORE_PASSWORD="$env:ATLASMART_TLS_STORE_PASSWORD" ` -v "${PWD}/ch26-tls:/tls" --entrypoint keytool cassandra:5.0.9 ` -exportcert -rfc -alias "atlasmart-sec-$n" -keystore "/tls/node$n.p12" ` -storetype PKCS12 -storepass:env ATLASMART_TLS_STORE_PASSWORD -file "/tls/node$n.crt"}
The 30-day self-signed identities make expiry observable in a free local lab. They are not a production PKI recommendation. Production certificates need approved CA profiles, Subject Alternative Names (SANs), key custody, renewal/revocation and trust-chain governance.
3. Configure client and internode TLS independently
server_encryption_options: internode_encryption: all optional: false legacy_ssl_storage_port_enabled: false keystore: /run/atlasmart-tls/node.p12 keystore_password: <INJECT_FROM_SECRET_SOURCE> truststore: /run/atlasmart-tls/truststore.p12 truststore_password: <INJECT_FROM_SECRET_SOURCE> require_client_auth: true require_endpoint_verification: trueclient_encryption_options: enabled: true optional: false keystore: /run/atlasmart-tls/node.p12 keystore_password: <INJECT_FROM_SECRET_SOURCE> require_client_auth: false
CLIENT TLS1. enabled=true, optional=true; rolling restart.2. Configure every cqlsh/driver with trust validation and verify TLS.3. Inspect system_views.clients for ssl_enabled/protocol/cipher/user.4. Set optional=false; rolling restart.5. Prove plaintext fails while TLS succeeds.INTERNODE TLS1. internode_encryption=all, optional=true; rolling restart.2. Verify UN state, restart, repair and streaming with encrypted peers.3. Set optional=false; rolling restart.4. If mTLS is required, verify every peer certificate/trust/SAN.5. Repeat node restart/repair/streaming tests after enforcement.
4. Observe TLS instead of trusting YAML
SELECT address,port,driver_name,driver_version,protocol_version, ssl_enabled,ssl_protocol,ssl_cipher_suite,usernameFROM system_views.clients;
A row with ssl_enabled=true proves that listed
active connection negotiated TLS. It does not prove all clients
use TLS, endpoint verification is enabled, internode traffic is
encrypted, or JMX is secure.
keytool -printcert -file /run/atlasmart-tls/node.crt# After replacing a file-based keystore/truststore in a controlled rotation:docker exec atlasmart-sec-1 nodetool reloadssl# Open new connections and repeat TLS/certificate evidence.
A new certificate can fail because the CA is not yet trusted, SAN/hostname is wrong, private key and certificate do not match, or the certificate is not yet valid/expired. Build overlapping trust where appropriate, canary the new material, reload/open new connections, revoke old material, and test an intentionally untrusted/expired path.
5. What to capture
- Authentication success/failure over TLS.
- Certificate subject, SAN, fingerprint and expiry without private-key disclosure.
-
system_views.clientsSSL evidence for expected users. - Node health plus repair/streaming after internode TLS enforcement.
- Plaintext denial after the transition.
- Rotation success and invalid/untrusted certificate failure.
Check your understanding
- Does PasswordAuthenticator encrypt traffic?
- Does client TLS protect repair/streaming?
- What does ssl_enabled in system_views.clients prove?
- Why use optional=true temporarily?
- What must rotation test?
Review the answers
1. No; authentication and transport encryption are independent.
2. No; internode encryption is separate.
3. Only that the listed active native connection negotiated TLS.
4. It permits a controlled rolling transition before TLS-only enforcement.
5. Trust overlap, SAN verification, key/cert match, validity window, reload/new connections, failure and rollback.
Production judgment
Security controls affect latency, availability and operator skill. Record Cassandra/JVM/driver versions, DC/racks/RF/CL, auth/TLS/JMX/network state, role inheritance, credential/certificate expiry, audit retention, backup encryption/access, patch status, repair/restore credentials and the application routing/retry/idempotency model. Re-run p50/p95/p99 latency and replica-failure tests after encryption/authorization changes. Data modeling still matters: partition/cardinality/TTL/tombstone/compaction/repair/SAI/vector choices can change sensitive-data exposure and resource-denial risk.
Do not treat a private subnet, one superuser password, client TLS or one audit stream as sufficient. Managed Cassandra may operate some server certificates, JMX, upgrades or backups, but application identities, permissions, client trust, data classification, secret use and incident response still have explicit owners. Migration/rollback must retain a tested administrative path and prevent coordinator-dependent security drift. Lesson 4 protects the other privileged surfaces: JMX, listener exposure, credentials, configuration secrets and backups.
Summary and next step
This lesson’s concepts, evidence path, failure boundaries, and production judgment should now be explicit enough to verify rather than assume. Re-run the check-your-understanding prompts and preserve any lab evidence you need before changing or cleaning up the environment.
Next, continue to Protect JMX/Management Interfaces, Credentials, Network Paths, Backups, and Configuration Secrets.
Authoritative references
Security defaults, algorithms, tooling and deprecations are version-sensitive. Re-check the target Cassandra/JVM/driver distribution and organizational cryptographic policy before production rollout.