Putting authentication on the shoulders of the application developer makes sense if Cassandra cluster is behind firewall and services may safely interect with the cluster directly. But if I need to connect to the cluster that's not in my local net - authentication will be necessary. Of course, it's always possible to use such tools as http://www.stunnel.org/, but authentication support would be nice to have...
On Wed, Nov 11, 2009 at 5:40 PM, Coe, Robin <robin.coe@bluecoat.com> wrote:
Just going to chime in here, because I have experience writing apps that use JAAS and JNDI to authenticate against LDAP and JDBC services.  However, I only just started looking at Cassandra this week, so I'm not certain of the premise behind controlling access to the Cassandra service.

IMO, auth services should be left to the application layer that interfaces to Cassandra and not built into Cassandra.  In the tutorial snippet included below, the access being granted is at the codebase level, not the transaction level.  Since users of Cassandra will generally be fronted by a service layer, the java security manager isn’t going to suffice.  What this snippet could do, though, and may be the rationale for the request, is to ensure that unauthorized users cannot instantiate a new Cassandra server.  However, if a user has physical access to the machine on which Cassandra is installed, they could easily bypass that layer of security.

So, I guess I'm wondering whether this discussion pertains to application-layer security, i.e., permission to execute Thrift transactions, or Cassandra service security?  Or is it strictly a utility function, to create a map of users to specific Keyspaces, to simplify the Thrift API?


-----Original Message-----
From: news [mailto:news@ger.gmane.org] On Behalf Of Ted Zlatanov
Sent: November 11, 2009 9:22 AM
To: cassandra-user@incubator.apache.org
Subject: Re: bandwidth limiting Cassandra's replication and access control

On Tue, 10 Nov 2009 17:09:44 -0600 Jonathan Ellis <jbellis@gmail.com> wrote:

JE> 2009/11/10 Ted Zlatanov <tzz@lifelogs.com>:
>> I see all the methods implementing the server interface in
>> org.apache.cassandra.service.CassandraServer.  Is that where the
>> authentication should happen?  Should I use JAAS (LDAP+PAM+other
>> backends) or is there something else preferred?

JE> Right, CassandraServer is the first non-generated stop for Thrift connections.

JE> JAAS looks like the standard java way to do this sort of thing, which
JE> makes me a little suspicious. :)

I looked for other solutions, but nothing was as convenient.  The docs
for the NIS auth backend show incorrect sample data (the LDAP sample is
copied) which makes me a lot suspicious.  It's not too enterprisey, though.

JE> But if you're already familiar with that, let's run with it.

I will learn it, I don't know it well yet.  Bear with me; discussion
follows.  Should we move this to the devel list, BTW?

>> Does libThrift allow persistent state per client somehow or do I have to
>> implement my own security tokens?  I don't see a way to track the client
>> in any of the Cassandra services currently so I suspect libThrift is
>> stateless on its own.

JE> Yes.  Since we're using the thrift threaded server, setting up a
JE> threadlocal from a login method and leaving the other methods alone
JE> would be my preferred approach.

Is it OK to keep the local auth info as a field in the CassandraServer
instance or is another place better?

JE> Ultimately what I'd like is to have a client authenticate to a
JE> specific keyspace.  Then we'd drop the keyspace argument from the
JE> other methods.

It looks like JAAS lets us use a jaas.conf file to specify the
authentication backend.  The application just needs to specify the
java.security.auth.login.config property as the full name of the
jaas.conf file.

The JNDI login module (LDAP and NIS) supports these properties,
according to the docs at http://java.sun.com/javase/6/docs/jre/api/security/jaas/spec/index.html:


before login() is called.  The other JAAS modules don't support that
(AFAICT they only work on the current user) so we'd only be able to
authenticate based on NIS or LDAP, or other JNDI providers.  This should
support at least Active Directory and most Unix shops.

As far as authorization after authentication, JAAS supports config files
like this (from the tutorial):

   grant codebase "file:./SampleAction.jar",
       Principal javax.security.auth.kerberos.KerberosPrincipal
           "your_user_name@your_realm"  {

      permission java.util.PropertyPermission "java.home", "read";
      permission java.util.PropertyPermission "user.home", "read";
      permission java.io.FilePermission "foo.txt", "read";

The Principal is the user ID.

We should be able to use anything that extends java.security.Permission
here; I think you're suggesting a KeyspacePermission but we should also
have a ClusterPermission.  I think we should allow wildcards in the
resource name.

This seems like a reasonable way to configure things and it does not
require any changes to the existing configuration files.  I like that;
separating security policies from the other configuration is always a
good thing.

See the tutorials for the details, starting at:


The actual auth method is pretty simple then.  Passing the password in a
non-Kerberos environment is risky but I am not sure of the right way to
encrypt the channel just for the password.  Encrypting just the login
info requires some thought as well.  Maybe someone has done this before?
For now the auth can just be

public void authenticateUser(Map<String, String> credentials, String cluster, String keyspace) throws ???

where the credentials are just the 'user' and 'password' keys in that map.

If there are no objections I'll put together a patch.


with best wishes,
Alexander Vushkan