Ayende @ Rahien

My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:


+972 52-548-6969

, @ Q c

Posts: 6,130 | Comments: 45,558

filter by tags archive

Handling complex security conditions with Rhino Security

time to read 4 min | 655 words

I got an interesting question about handling complex security conditions that I thought would be perfect to illustrate the underlying design principles for Rhino Security.

The problem is securing surveys. A survey has a start date, an end date, can be marked as applicable to a specific population, may be public or private, etc. The specification says that a survey that the user does not own should only be visible to a user iff:

  • The survey is public
  • The survey is active
  • The survey has started
  • The survey has not ended
  • The survey is for a population that the user is a member of

Can you imagine the amount of work that is required to set up this sort of rule properly? And apply it consistently all over the application? It is exactly for those sort of scenarios that I created Rhino Security.

Let us see how we are going to design the security infrastructure for the application. We are going to specify the following:

  • The owning user for a survey is allowed access at a high level:
        .Allow("/Survey") // allow to do everything on a survey
  • If the survey is for a particular population, that population is created as a user group, and we create a rule that allow that user group access to the survey:
        .For(survery.Population.Name) // the user group name
  • The other permissions are specified globally, we need to do an and between all of them, and Rhino Security doesn’t give us direct support for that. What we do get, however, is Deny and levels, so we specify those permissions using the following:
        .For("Everyone") // all users
        .On("Inactive Surveys") // an entity group
        .For("Everyone") // all users
        .On("Private Surveys") // an entity group
        .For("Everyone") // all users
        .On("Completed Surveys") // an entity group
        .For("Everyone") // all users
        .On("Unstarted Surveys") // an entity group

Now, that we have set it up, what we need to do now is to add and remove the survey to the appropriate entity groups, based on whatever business conditions that we have. Note that those are explicit state transitions. This isn’t just us setting IsActive and IsPublic flag, or verifying date ranges. We have to take explicit action to add and remove the entities from the appropriate groups.

There are two reasons of doing things in this way, the first, it make it significantly easier to handle security, since we don’t have murky rules or implicit state transitions. Second, from a design standpoint, it leads to a situation where we don’t work with just dump objects and queries, but meaningful transitions between states.

Yes, that does implies that you would have to have some sort of a background process to move surveys between groups based on time. That is a good thing, but I talked about this in another post.



Why don't use a DSL for that?

Ayende Rahien


Take a look at the original drive for Rhino Security, a DSL can allow you to filter in memory, but it won't work if you want to filter in the DB

Anders Bondehagen

I implemented Rhino Security in a survey tool earlier this year =) I guess then It's not only me that found it to be a useful tool in this context.

Diego Jancic

Hi Oren,

Is that open source? I've read a couple times about it, but I never couldn't find the project. Thanks

Comment preview

Comments have been closed on this topic.


  1. How to waste CPU and kill your disk by scaling 100 million inefficiently - 11 hours from now
  2. RavenDB Conference 2016–Slides - about one day from now

There are posts all the way to Jun 01, 2016


  1. The design of RavenDB 4.0 (14):
    26 May 2016 - The client side
  2. RavenDB 3.5 whirl wind tour (14):
    25 May 2016 - Got anything to declare, ya smuggler?
  3. Tasks for the new comer (2):
    15 Apr 2016 - Quartz.NET with RavenDB
  4. Code through the looking glass (5):
    18 Mar 2016 - And a linear search to rule them
  5. Find the bug (8):
    29 Feb 2016 - When you can't rely on your own identity
View all series


Main feed Feed Stats
Comments feed   Comments Feed Stats