We had a recent discussion in Slack about how to potentially use the
OPTIONS and SUPPORTED messages in the existing CQL protocol to allow the
server to advertise more than one authentication method and allow the
client to then choose which authenticator to use. The primary use case here
is to allow seamless migration to a new authenticator without having to
have all parties involved agree on a single class (and avoid a disruptive
change). There's already a ticket open that was focused on making a change
to the binary protocol (
https://issues.apache.org/jira/browse/CASSANDRA-11471) but I think that we
can accomplish this in a backwards compatible way that avoids a change to
the protocol itself.

What I propose is to allow a server configured for this graceful auth
change to send an additional value in the [string multimap] body of the
SUPPORTED message that indicates which authenticators are supported, in
descending priority order. For example, if I wanted to migrate my server to
support both PlainTextAuthProvider and some new MyAwesomeAuthProvider, I
would configure my client to query options and the server would respond with

'AUTHENTICATORS': ['MyAwesomeAuthProvider', 'PlainTextAuthProvider']

The client can then choose from its own supported providers and send it as
part of the STARTUP message [string map] body:

'AUTHENTICATOR': 'MyAwesomeAuthenticator'

I'm not good with naming so feel free to propose a different key for either
of these map entries. In any case, the server then validates that the
client-chosen authenticator is actually supported and would then proceed
with the AUTHENTICATE message. In the case where the client sends an
invalid/unsupported authenticator choice, the server can simply respond
with an AUTHENTICATE using the most-preferred configured authenticator.

I think this is a better approach than changing the binary protocol because
the mechanism already exists for negotiating options and this seems like a
natural use case that avoids having to create an entirely new version of
the protocol. It does not appear to conflict with the existing protocol
definition but I'm not 100% certain. Section 4.1.1 discusses "Possible
options"  for the STARTUP message (
https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v4.spec#L296),
but that's an unfortunate use of English that's ambiguous as to whether it
means "The only ones supported" or "Supported but not exclusively".

I've taken a look at the Java and Python driver source so far and I can't
find anything that would seem to cause a problem by returning a SUPPORTED
multimap entry that the client isn't aware of (in both they would appear to
ignore it), but I'll also admit that this is the first time I've looked at
this part of the client code and I could be missing something. Is anyone
aware of possible problems that would be caused by using this approach? In
particular, if there are clients that strictly validate all entries in the
SUPPORTED map then this could cause a problem.

Worst case, we may still need a protocol version bump if the enumeration of
STARTUP options is intended to be strict, but at least this would not
require a new message type and would fit into the existing framework for
negotiation between client and server.

Thoughts, questions, or concerns would be appreciated.

Cheers,

Derek

-- 
+---------------------------------------------------------------+
| Derek Chen-Becker                                             |
| GPG Key available at https://keybase.io/dchenbecker and       |
| https://pgp.mit.edu/pks/lookup?search=derek%40chen-becker.org |
| Fngrprnt: EB8A 6480 F0A3 C8EB C1E7  7F42 AFC5 AFEE 96E4 6ACC  |
+---------------------------------------------------------------+

Reply via email to