PEM credentials and extensible TLS configuration in Cassandra 4.1
The upcoming Cassandra 4.1 release can consume PEM credentials directly through a configurable SSL context factory. Its implementation preserves Java key managers while removing an external conversion step.
Certificate automation becomes harder when one service requires credentials in a different format from everything around it. Cassandra's upcoming PEM support addresses that problem at the point where it constructs its TLS context. A deployment with PEM credentials will be able to supply those credentials directly, without first maintaining a separate JKS artifact for Cassandra.
Maulin Vasavada's March 10 explanation describes this work for Cassandra 4.1. It presents both built-in PEM support and a configurable SSL context factory. These are related changes with different consequences. PEM support removes a conversion step for a common credential format. The factory interface permits a deployment to customize how Cassandra obtains the material used to create its SSL context.
I value changes that make Cassandra easier to integrate with an existing operational environment. Its distributed architecture already needs a reason to be in a system. Requiring a separate credential conversion process adds administration without changing the reason for choosing the database.
The conversion moves inside Cassandra
The article describes the existing route through PKCS#12 to JKS for operators starting with PEM credentials. That route introduces another generated artifact to maintain. Direct input avoids requiring the operator to perform that conversion before Cassandra can read the credentials.
The PEM factory implementation available before this announcement shows what happens instead. PEMBasedSslContextFactory extends FileBasedSslContextFactory. It parses the PEM input, constructs a Java KeyStore, and uses that store to initialize the key manager or trust manager. Its internal target store type is PKCS12.
This preserves the Java TLS machinery while changing the input accepted from the deployment. Cassandra still needs structured private key and certificate objects. It now constructs those objects itself from the text supplied by the operator. The factory documentation says that the private key must use PKCS#8 and that the certificates are X.509 certificates. A file with PEM delimiters is therefore not sufficient by itself. The contents must represent the supported kind of object.
The implementation also ignores the existing store_type setting for this factory. That follows from the mechanism. The configured input is PEM, and the factory chooses the type of the temporary Java store it builds. Setting a JKS store type alongside the PEM factory does not turn the input into a JKS file.
Identity material and trusted certificates remain separate
For its key manager, the factory extracts a private key and the corresponding certificate chain from the same PEM content. It rejects input that supplies no certificates for that chain. The combined input therefore needs both the key and the certificates that identify it. Supplying a private key alone does not satisfy the implementation.
Trust material takes a different path. The factory extracts certificates from the trusted PEM content and places each in a certificate entry in its internal store. That store initializes the trust manager. It does not require a private key because its purpose is to identify certificates the process trusts, not to supply the process's own identity.
The distinction carries through to the configuration names. Inline identity material uses private_key, despite containing the associated chain as well. Inline trust material uses trusted_certificates. For file input, the existing keystore and truststore names remain, but their contents are PEM when this factory is selected.
The following fragment illustrates that selection for internode encryption configuration. It assumes an unencrypted PKCS#8 key and its certificate chain in the first file, and trusted certificates in the second. The paths are examples, and the fragment must be merged into the rest of the server encryption configuration.
server_encryption_options:
ssl_context_factory:
class_name: org.apache.cassandra.security.PEMBasedSslContextFactory
keystore: conf/node-identity.pem
truststore: conf/trusted-ca.pem
The class name uses Ssl, which matters when configuring the implementation by its Java name. Selecting that factory describes credential loading. It does not replace the surrounding settings that determine which connections use encryption or which peers must authenticate.
Input sources must be unambiguous
The implementation accepts inline content or file content, but it rejects a conflicting configuration for the same kind of material. If the configured keystore file exists and an inline private key is also present, construction fails. The corresponding check rejects an existing truststore file combined with inline trusted certificates.
That detail affects a configuration assembled from multiple templates. Adding inline credentials while leaving an older file path in place can create a conflict if the old file still exists. The error does not establish that either credential is malformed. It establishes that Cassandra has been given competing sources for the same input.
Password handling also has specific rules. The factory reads private_key_password for inline parameters and falls back to keystore_password when that parameter is empty. If both contain nonempty, different values, it rejects the configuration. The PEM truststore does not use a password, and the implementation warns that a supplied truststore_password is ignored.
These rules make the choice of input source part of the configuration contract. A templating system cannot safely treat every existing keystore setting as a harmless default after adding the new factory. Some settings supply fallback values, some conflict with inline material, and one has no meaning for the PEM truststore.
Reloading depends on where credentials come from
The built-in factory supports hot reloading for file-based material. Its initHotReloading method adds the keystore file to the watched list when identity material is file-based and the file exists. It performs a corresponding check for file-based trusted certificates. Inline values do not become watched files merely because the factory supports hot reloading in another mode.
Vasavada's article also includes a Kubernetes-specific factory example. That example uses environment variables for PEM content and mounted timestamp files to detect credential changes. It demonstrates the purpose of the extension interface, but it is a custom implementation with its own configuration parameters. The built-in PEM factory does not automatically interpret those Kubernetes-specific parameter names.
I prefer file-based integration when the credential delivery mechanism already writes files that the built-in factory can consume. A custom factory is justified when the source or reload behavior requires code that the built-in implementation does not provide. Either choice retains the distinction between obtaining updated material and constructing a new TLS context from it.
As of this announcement, the work belongs to the upcoming 4.1 release. The concrete improvement is that an operator can choose a PEM input path while Cassandra continues to build the Java key and trust managers it needs. The file and inline modes have explicit validation rules, and file-based reloading gives credential delivery a defined connection to the factory's lifecycle.