Skip to content

CEP-50/CASS-21334: Server negotiates authenticator per client connection#4773

Draft
jcshepherd wants to merge 30 commits intoapache:trunkfrom
jcshepherd:jcshepherd/21334/trunk
Draft

CEP-50/CASS-21334: Server negotiates authenticator per client connection#4773
jcshepherd wants to merge 30 commits intoapache:trunkfrom
jcshepherd:jcshepherd/21334/trunk

Conversation

@jcshepherd
Copy link
Copy Markdown
Contributor

Server negotiates authenticator per client connection.

This is the main server-side implementation of CEP-50 (https://cwiki.apache.org/confluence/display/CASSANDRA/CEP-50%3A+Authentication+Negotiation), enabling administrators to configure authentication negotiation with multiple authenticator options, and the server to negotiate an authenticator with the client for each connection. Clients that don't support authentication can connect and authenticate as they always have.

patch by jcshepherd; reviewed by for CASSANDRA-21334
Assisted-by: Amazon Q CLI 1.19.6 claude-sonnet-4.5


The [Cassandra Jira](https://issues.apache.org/jira/projects/CASSANDRA/issues/)

… (CASSANDRA-20834 for CEP-50)

With negotiated authentication (CEP-50), nodes may be configured with multiple authenticators. Prior to this change,
a number of areas in the code assumed that there was a single configured authenticator and contained logic that
switched depending on the authenticator type. This logic won't work when multiple authenticators can be configured.
This change eliminates most calls to DataDescriptor.getAuthenticator(), by enabling individual authenticators to
declare the role attributes they support, requiring callers to specify the type of authenticator they're looking
for, and directly returning whether the node can enforce authn or not rather than inferring it by the presence of
an authenticator.

Testing done: Unit tests for auth and config packages; d-tests for auth-related functionality (e.g. ColumnMasks).

patch by jcshepherd; reviewed by smiklosovic,tolbertam for CASSANDRA-20834
…RA-20834)

With negotiated authentication (CEP-50), nodes may be configured with multiple authenticators. Prior to this
change, a number of areas in the code assumed that there was a single configured authenticator and contained
logic that switched depending on the authenticator type. This logic won't work when multiple authenticators
can be configured. This change eliminates most calls to DataDescriptor.getAuthenticator(), by either requiring
dependencies to specify the type of authenticator they're looking for, or (in the case of authenticator-specific
role attributes) enabling individual authenticators to declare the role attributes they need.

patch by jcshepherd; reviewed by <Reviewers> for CASSANDRA-20834
…to DatabaseDescriptor.unsafeDaemonInitialization() in AuthConfigTest to enable each test to run against the appropriate auth config. (DatabaseDescriptor.daemonInitialization() can be invoked only once per unit test class execution and is not suitable for test cases exercising multiple configuration scenarios.)
… an object, not a list, and adding notes on why it matters. Still a sharp edge ...
…abled during node initialization, when all clients are system/internal
… handshake, client super- and anonymous-user determination is made based on the authenticator used by the client, not the node's default authenticator
…d of StorageService. Auth setup includes ensuring all negotiable authenticators are initialized.
…ator. Test updates to initialize client state and use a marker class to distinguish between authenticator returned by default vs by negotiation
…ured authenticator requires authentication. ClientState disallows anonymous (unauthenticated) users from assuming super user privileges if any configured authenticator requires authentication.
…thentication, and validates authorizer compatibility with the authentication configuration
# Conflicts:
#	src/java/org/apache/cassandra/config/DatabaseDescriptor.java
#	src/java/org/apache/cassandra/service/ClientState.java
#	src/java/org/apache/cassandra/transport/messages/StartupMessage.java
#	test/unit/org/apache/cassandra/auth/AuthConfigTest.java
…d cache in PasswordAuthenticator as a singleton, minor code and comment clean-up elsewhere
@jcshepherd jcshepherd marked this pull request as ready for review April 27, 2026 22:44
// work with PasswordAuthenticator, so log a message if some other authenticator
// is in use and non-default values are detected
if (!(authenticator instanceof PasswordAuthenticator || authenticator instanceof MutualTlsAuthenticator)
if (!(authConfig.defaultAuthenticator instanceof PasswordAuthenticator || authConfig.defaultAuthenticator instanceof MutualTlsAuthenticator)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this check should probably be made if any configured authenticator is a password or MTLS authenticator, not just the default. .

// in case these rely on each other.

authenticator.validateConfiguration();
authConfig.defaultAuthenticator.validateConfiguration();
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be invoked on all authenticators, not just the default.

// Check all negotiable authenticators (includes default)
for (IAuthenticator auth : authConfig.negotiableAuthenticators)
{
if (!auth.requireAuthentication())
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/auth/authenticator/ for clarity please.

@jcshepherd jcshepherd marked this pull request as draft April 27, 2026 23:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant