Hi all, I've been doing some work around HBase security and I've identified a few enhancements that would make AccessController provide better audit information for people interested in that. There are three different items which are not necessarily related to each other.
(i) Lack of column family information in audit logs I'd actually consider this a bug, more than an enhancement. The culprit here is AccessController.permissionGranted(). If you look at that method, it will generate audit events containing column family / qualifier information only when the required permission for that specific family / qualifier is denied. If permission is granted, you get an audit message that contains the table name, but no family / qualifier. I think the correct thing here would be to list the affected family / qualifiers when permission is granted, too. In the deny case, it's a little bit hazier: do we list all families / qualifiers, the first one to have a permission denied, or all families / qualifiers for which permission was denied? This question is also mildly related to (iii) below. (ii) The access controller does not work if authentication is disabled. This sounds obvious, right? Why would you need an access controller if there is no security configured? I think it would still be useful to collect auditable events in this case. The user information will be bogus or non-existent, but at least anyone interested will be able to collect access information for their service. This could be done by creating another coprocessor, but that would require replicating some of the logic in access controler (to decide which permissions to log in the audit event), or refactoring that logic into a helper class or something. (iii) There's no easy way to customize processing of audit events. Audit events are written to a log appender in a private method in AccessController.java; this means anyone who wants something different, like writing this data to a database, has to go through the logging system to do it. This is sub-optimal since it means having to parse a log message, and potentially losing information in the process. My preferred approach is to separate audit event creation (AccessController.java) from audit event storage (currently also in AccessController.java) by means of an "audit logger" interface. A new config option can tell the AccessController to instantiate one (or more, although I don't see much use in that) "audit logger", and it would then call that logger instead of (or in addition to) sending the log message to the logging subsystem. I actually have a working prototype for this approach on top of HBase 0.92, I can post the patch somewhere if anyone is interested. A different approach would be to make logResult() in AccessController protected, so that it can be subclassed, achieving similar functionality. But I don't like how this would create tight coupling between AccessController and the audit logging code. So I think that covers what I've been looking at; sorry for the long-ish e-mail. Feedback always welcome. -- Marcelo
