Read on your own risk!

Main menu

Post navigation

Adding simple authentication to Cassandra

Today I was asked to set up user authentication in Cassandra, so we could stop using the “default” user with unrestricted access only. I have to say that I was really surprised when I noticed that there’s NO out-of-the-box authentication and authorization framework in it. Luckily, it can be easily enabled in a few steps which I’m going to show you.

One important thing – SimpleAuthenticator we’re going to use is in the “examples” directory of Cassandra package. It’s because it is considered to be very simple and not very safe (it was even called a “toy” in one of Cassandra’s Jira tasks), so DO NOT rely on it as on a serious protection tool for your system. However it still fits many requirements (i.e. you don’t want user to make a mess in a Column Family he doesn’t need to work on) so you may find it useful. You have been warned.

First of all – you will need Ant 1.8 and Java SDK for building Cassandra’s jar file. Ant is available in Ubuntu’s apt repo by default. Sun’s (or actually Oracle’s) Java can be found in an ferramroberto’s alternative repository and installed this way:

Now we’re going to build Cassandra with the authentication classes we need. For this you need to download the source package of Cassandra which can be found here: http://cassandra.apache.org/download/ – I’ve picked the latest beta package, but this tutorial should not be version-dependent. Once you download it, unpack it end enter the directory:

The two classes we need to be available for cassandra are: org.apache.cassandra.auth.SimpleAuthenticator and org.apache.cassandra.auth.SimpleAuthority. We have to copy them to the proper source code directory:

After doing this we can build Cassandra and – once it’s build – make a jar file. It may take a few minutes:

ant
ant jar

Having jar file we have to (OK, we don’t have to, but it’s a good idea) move it somewhere – i.e. to Cassandra’s jar directory – and substitute an existing symlink with a new one, refering to the freshly built jar:

The second one holds the access definitions in a format: keyspace.cfname.
and a list of user having this privileges. Privileges can be which means read-only or which means read-write. I told you, that this permission system is very simple. Additionaly you can define users which have permission to modify keyspaces – it can be done with statement. Here’s an example of this file:

Then, tell Cassandra to use the proper Authenticator and Authority classes. You can do it by modifying /etc/cassandra/cassandra.yaml file – find authenticator and authority settings and change them to:

The last thing is to tell Cassandra to use the two config files described above when SimpleAuthenticator or SimpleAuthority ask for them. This can be done – for example – by modifying /etc/init.d/cassandra script directly, but it is a much better and cleaner solution to do it via JVM_OPTS in /etc/cassandra/cassandra-env.sh by adding:

One more thing – if you want to, you can store your passwords as a MD5 hash (I didn’t do it in this example, but it works too and is, obviously, a nice idea) by adding one more variable in this (/etc/cassandra/cassandra-env.sh) file:

13 thoughts on “Adding simple authentication to Cassandra”

I’ve made a little update today – one information was wrong (MD5 password is not a cassandra.yaml setting but JVM one) and one thing (way of passing “-D” parameters) was done in a way which I didn’t like. Both things are fixed now.

Yes, you’re mostly right, but I guess that’t the reason why SimpleAuthenticator was moved to “examples” directory. Of course I agree that it’s not good that you can access “system” keyspace as any (as I guess) user and list the keyspaces, but what was important for me is that even if you can do it, you are still unable to modify CFs. When I log in with:

cassandra-cli -u myusername -pw mypassword -k system

and try:

[myusername@system] list IndexInfo ;
(...)
#<User myusername groups=[]> does not have permission READ for
/cassandra/keyspaces/system/IndexInfo
InvalidRequestException(why:#<User myusername groups=[]> does not
have permission READ for /cassandra/keyspaces/system/IndexInfo)

And yes – he can create keyspaces because it has a “modify-keyspaces” permission. If you try to log in as a different user, who’s not on that list, you’ll get:

[other@system] create keyspace new_keyspace;
#<User other groups=[]> does not have permission WRITE for
/cassandra/keyspaces

I’d say it’s satisfying solution for my case. I completely agree with you that it’s not something what we could call “good” or “safe” in general, but as I mentioned in the second paragraph: “(…) DO NOT rely on it as on a serious protection tool for your system. (…) You have been warned.” :)

The other thing is that user having “modify-keyspaces” privilege is still UNABLE to create CF’s, which is a problem for me now and I don’t think it should work this way. I’ve asked a question about this setting on Cassandra’s mailing list today. When I get some more explainations on this – I’ll write something about it.

I also have another problem with Cassandra.
I Want to perform wild searches on the database, but not lucky enough, came to know that Cassandra does not support wild search.(e.g.select KEY,username,password from Users Where username=’%hello%’)

Unluckily, Cassandra wasn’t meant to work this way – as you already know there’s no way to do such queries.

For many cases you can do some “tricks” that will mimic behavior you need with a little help of additional Column Families that will be a kind of “index” for – refering to your example – Users CF. You may take a look at this presentation for some ideas: Cassandra Basic Indexing, but – anyway – I think in your specific case it won’t work – creating a CFs with *all* possible string combinations that could match your usernames is just ridiculous ;) However, you may find it usefull for other cases (i.e. prefix search) you work on.

In this particular case, at first, I’d reconsider if Cassandra is the best match for you. There are other solutions that offer such functionality and – simply – are just made to work in the way you expect. Take a look at MongoDB – it’s a really good solution. If you want to stay with Apache (“You will never get fired for choosing Apache stuff” ;) ), take a look at CouchDB – I don’t know it well, but it may fit your requirements as well.

Secondly, if you need Cassandra because of other reasons – think about “caching” the data you need in one of the data stores I mentioned above. You’ll still be able to store your data in Cassandra, but the “cache frontend” will provide the “wildcard” functionality you need.

The configuration normally do everything in accordance with the document.error
ERROR 11:57:21,625 Fatal configuration error
org.apache.cassandra.config.ConfigurationException: When using org.apache.cassan
dra.auth.SimpleAuthenticator passwd.properties properties must be defined.
at org.apache.cassandra.auth.SimpleAuthenticator.validateConfiguration (S
impleAuthenticator.java: 141)
Can not get System.getProperty (SimpleAuthenticator.PASSWD_FILENAME_PROPERTY);
1.1.6 version crash