Monday, March 4, 2013

Access your organizational data securely and transparently

What do I have to hide?

If you are dealing with an information system, you always have something to hide. Maybe not at first, but as your system grows, it starts to accommodate more users of various roles and positions inside or outside the organization. Perhaps the types of information you store diversify as well. At some point, you're going to need some boundaries to protect that information, or your data management will end up looking like a Harlem Shake.
For instance, say you have a software system for managing scientific experiments and results. Its purpose is to allow the public easy access to research and to allow scientists to share their knowledge. So why hide anything? It may seem at first sight that you would not need any security here, but let us consider some example use cases:
  1. A general user who wants information about children's safe attachment
  2. A biologist wants to see the latest news about stem cell research
  3. A member of a cross-disciplinary research project wants to see its progress
You can see how all of these users are out for the same type of information (results of research), but as the architect of the system, you would want to give them different levels of access to it, since you wouldn't to expose the details of an ongoing project to anyone but the team and if you're a biologist you can probably see some partial and unverified results that perhaps you wouldn't want to share with the general public at this point.
Let's try to describe a simple security layer to address those needs.

Building a protection layer

Unknown location

The easiest and simplest way to keep a secret. You want to hide something? Don't tell anyone where it is. This is similar to how Google allows you to share photo albums with "Anyone with the link". Given that the link is random enough, it would be pretty hard for someone to locate it. However, once the link is leaked you lose control over it. You give one colleague the link to your research results and he sends it to his journalist friend and you don't know what happens next.

Password protecting

So maybe just put a password on anything you want to keep safe? Again, the password could be leaked, but even if it doesn't or you are able to change it in time, this is problematic since now you need to manage a whole range of passwords for all your data and remember everyone else's passwords. This is very cumbersome and inefficient and doesn't provide real security.

User identity

Why don't we approach this from a different angle and try to identify the user first and then let him access the application? Let's assume our program has some sort of login mechanism in which it identifies the user. The user then tries to find the relevant information. This approach works better than the previous ones since there is no need for user interaction after the first identification (which can sometime be done automatically using Singe Sign On). Also, the control is granular and dynamic per user, so we have lots of control.
But, as Uncle Ben once said, with great control comes great complexity. We now have the responsibility to assign (and maintain!) the different permissions for all users and data which can amount to thousands or even millions of combinations.

A simple, scalable solution

So we come to the conclusion that while using user based permissions is secure enough, we need a way to treat the users as groups with common properties rather than as individuals. If we could label the data in a smart way, users will have an easier time accessing it.
How can we do this? There are several common ways:
  1. Flat labeling – marking pieces of data with some sort of label or tag is the basis of Web 2.0. We can mark each project with a unique label, if needed.
  2. User groups – we can assign the user to various groups according to his affiliation. For example, "biologists from Oxford" can be such a group if we want to allow them to share information only they will see. Another option is to separate "Biologists" and "Oxford" and use some sort of combination logic.
  3. Roles – If you wish to expose only some of the data to general users, this can be accomplished by assigning a hierarchy of roles and only allowing "scientists or above" to view it.
Accessing the data can be done via a (simplified) method such as:


IEnumerable<ResearchData> GetResearchData()
   return DAL.GetData<ResearchData>();

Notice a couple of things about this method:

  • The DAL object is some object that allows fetching data from a DB or a service without being aware of security limitations. Don't allow direct access to it.
  • It has a "Secured" attribute with the value set to true, which means it will trigger some code using an AOP technique.
This is what the implementation of "Secured" should look like:

public class SecuredAttribute : AOPAttribute

public override void OnSuccess(MethodExecutionArgs args)
   Credentials creds = GetUserCredentials();
   args.ReturnValue = creds.Filter(args.ReturnValue);

GetUserCredentials() gets a class that consists of the grouping of users which we talked about before and has logic to filter the input data with.


In this post, I gave an example of a security layer implementation. Of course, every system has its unique needs and should be considered independently. However, I feel there are general principles which hold true for all cases and they should be followed as guidelines:

  • Keep your security flexible – you never know when a security level for data or users will change.
  • Separate concerns – let your business logic do its thing, don't mix in security. Try to do as little as marking a method with an attribute, and perhaps not even that. Notice how in the example the logic of filtering by credentials is centralized in a single location, easy to understand and change. NEVER CHECK FOR USER CREDENTIALS IN DOMAIN CODE.
  • Identify your roles – This is important because once you've managed to map credential types to use cases, you've solved the main logical challenge. Don't get stuck too much on this though, since if you separate concerns properly, you will be able to change this later on.
Good luck!

No comments:

Post a Comment