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,125 | Comments: 45,492

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. RavenDB 3.5 Whirlwind tour: I need to be free to explore my data - 7 hours from now
  2. RavenDB 3.5 whirl wind tour: I'll have the 3+1 goodies to go, please - 3 days from now
  3. The design of RavenDB 4.0: Voron has a one track mind - 4 days from now
  4. RavenDB 3.5 whirl wind tour: Digging deep into the internals - 5 days from now
  5. The design of RavenDB 4.0: Separation of indexes and documents - 6 days from now

And 11 more posts are pending...

There are posts all the way to May 30, 2016


  1. The design of RavenDB 4.0 (14):
    05 May 2016 - Physically segregating collections
  2. RavenDB 3.5 whirl wind tour (14):
    04 May 2016 - I’ll find who is taking my I/O bandwidth and they SHALL pay
  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