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 /
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
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.
Andrew Purtell 2012-07-12, 21:56
Marcelo Vanzin 2012-07-12, 22:34
Andrew Purtell 2012-07-12, 22:54
Marcelo Vanzin 2012-07-12, 23:42