Status

Current state: Done

Discussion threadDev List

JIRACASSANDRA-16456

Released: 4.x

Please keep the discussion on the mailing list rather than commenting on the wiki (wiki discussions get unwieldy fast).



Scope

cqlsh

Motivation

Currently the Cassandra drivers offer a plugin authenticator architecture for the support of different authentication methods.  This has been leveraged to provide support for LDAP, Kerberos, and Sigv4 authentication.  Unfortunately, cqlsh, the included CLI tool, does not offer such support.  Switching to a new enhanced authentication scheme thus means being cut off from using cqlsh  in normal operation.

While it's possible to code around this by writing tools that extend the base class of cqlsh, we aim to build support that aligns with the mechanism used by Cassandra drivers.

Goals

 Modify cqlsh.py code to be able to dynamically load a class extending AuthProvider for use as the authentication mechanism when making a connection.  Extension details (class and module) should be specified via cqlshrc (current mechanism for configuration).

Timeline

11/30 - Complete work and submit

Mailing list / Slack channels

Mailing list: 

Slack channel: 

Related JIRA tickets

JIRA(s): 



Motivation

Currently the Cassandra drivers offer a plugin authenticator architecture for the support of different authentication methods.  This has been leveraged to provide support for LDAP, Kerberos, and Sigv4 authentication.  Unfortunately, cqlsh, the included CLI tool, does not offer such support.  Switching to a new enhanced authentication scheme thus means being cut off from using cqlsh  in normal operation.

While it's possible to code around this by writing tools that extend the base class of cqlsh, we aim to build support that aligns with the mechanism used by Cassandra drivers.

Audience

The primary audience of this tool are Cassandra DevOps / Operators (people who deploy, run & maintain C* clusters), and anyone who has occasion to use the cqlsh tool.

Proposed Changes

We propose the following changes to the cqlsh utility.

  • Adding support in cqlshrc properties to allow access to Cassandra Python driver authenticators
  • Adding additional cqlshrc properties to allow instantiation of plugin authenticator.
  • Adding dynamic loading of AuthProvider classes to cqlsh utility.

Adding additional cqlshrc properties to allow access to Cassandra Python driver authenticators


There are already auth providers that exist in the standard Python drivers which are inaccessible to CQLSH.  For example: SASLAuthProvider.

To make these work with the new system we would extend the cqlshrc file to have a configuration as the following:

[auth_provider]
classname=<class name>
module=<path to module>
classname=<MyProvider> other = value
someother = somevalue


Cqlsh, when invoked with this configuration, would create an instance of the given class name from the given module.

All elements in AuthProviderExtendentProperties would be fed to the AuthProvider’s constructor as a dict (for example {‘extendedparam1’:‘value’} ).  

An individual wanting to use a SaslAuthProvider in CQLSH, initialized in client code like this:

        sasl_kwargs = {'service': 'something',
                      'mechanism': 'GSSAPI',
                      'qops': 'auth'}
        auth_provider = SaslAuthProvider(**sasl_kwargs)


would merely need to provide the following cqlshrc, to use a similar Auth Provider instance in cqlsh.

[AuthProvider]

classname=SaslAuthProvider
module=cassandra.auth
service = something
mechanism = GSSAPI
qops = auth


Of course, there needs to be also server side of this implementation (or any other implementation, for that matter) but this is outside of the scope of this ticket and server-side custom authenticators are already possible to implement by implementing respective interfaces.

Adding additional cqlshrc properties to allow instantiation of plugin authenticator


The new heading for the cqlshrc would appear to be the following:

[auth_provider]
classname = <class name>
module = <path to module>
path = <path to python lib>
other = value
someother = somevalue


module and path would correspond to the arguments that are part of the built-in importlib functionality of Python. classname would correspond to the class name loaded.

To allow flexibility, all additional properties in AuthProviderExtendedProperties section would be sent to the constructor of the class as simple named properties.  This would allow a custom plugin to easily handle additional properties unique to its context (KDC, LDAP server, etc).


Dynamic loading of Custom AuthProvider class in cqlsh utility

Cqlsh would use the auth_provider section to instantiate the AuthProvider class, through the use of importlib and getattr functions.  The constructed auth_provider instance would then be passed as the auth_provider property of the Cluster constructor when cqlsh created the connection.

If the AuthProvider section is not specifically defined, PlainTextAuthProvider would be used.

Example of Custom Class Usage


Let’s suppose that I have downloaded a Python SAMLAuthProvider to my home directory under ~/samlplugin.

This contains a class located at  com.example.cassandra.driver.auth.SAMLAuthProvider that extends AuthProvider in the standard Python driver. Let’s also say constructing this requires a parameter called saml_file_path which is the complete path to the saml.conf file (a file which contains all the properties necessary to use SAML). Here is an example of using the class to create a connection when using the Python driver:

auth_provider = SAMLAuthProvider(saml_file_path="~/saml.conf")

cluster = Cluster(['endpoint'],  auth_provider=auth_provider)

session = cluster.connect()


                                  

To configure cqlsh to work I would add the following section to my cqlshrc file...

[auth_provider]
classname=SAMLAuthProvider
module=com.example.cassandra.driver.auth
path=~/samlplugin
saml_file_path=~/saml.conf

After doing so, when connecting via cqlsh it would immediately use SAML to authenticate me against the cluster.

New or Changed Public Interfaces

There would be no changes to the public interfaces for the Cassandra service itself.  The cqlshrc format would be changed to allow for the new AuthProvider, as well as associated documentation.


Compatibility, Deprecation, and Migration Plan

Existing users will not be impacted by this as it will be a new feature of cqlsh.  No existing behavior will be removed or altered in the operation of cqlsh.

Test Plan

Additional unit tests would be added to cqlshlib for new supported AuthProvider