Status
Current state: Done
Discussion thread: Dev List
JIRA: CASSANDRA-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):
- CASSANDRA-16983- Separating CQLSH credentials from the cqlshrc file
- CASSANDRA-11471 - Add SASL mechanism negotiation to the native protocol
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:
|
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:
|
would merely need to provide the following cqlshrc, to use a similar Auth Provider instance in cqlsh.
|
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:
|
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...
|
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