Thoughts about Access Control Lists in Ruby on Rails
When you’re implementing a web application that offers some sort of user management, you quickly get into the situation to think about permissions for these users. Usually you want to have groups of users (or „roles“ - I noticed that many in the Ruby on Rails field prefer the term roles here) that share permissions like „may write postings“, „may read profiles“ and these sort of things. Some time ago I started writing a web application and ran into this exact situation. I asked myself „What’s the best way to set up the most flexible sort of permission system, so anything can be permit or forbidden to anyone?“. My conclusion was that I had to use Access Control Lists (ACLs). Using ACLs the way I wanted to implement it, each object in my application would have had two additional objects: a requesting object and a requested object. Let’s say you have users and postings. Whenever you create a user you would create a requesting object myUser and a requested object myUser, too. Same with postings. Then I could define a simple 1:1 relationship between each requesting object and each requested object. For example: requesting object myUser shall have permission to read requested object myPosting. Or the other way round: requesting object myPosting shall have permission to read requested object myUser, too. Thinking about all the models you will have in a huge web application, you could easily define permissions for everyone to everything. But guess what - this system is rather complicated to implement. I am still not finished writing my Rails plugin for this and I don’t think I will be able to finish it within the next few weeks or something. My idea behind this ACL plugin I was going to write was, that I needed one single plugin that can handle all the needs I will ever have in an web application. If this plugin is finally ready, I can use it for huge and small projects as well. You don’t need its full power? No problem, just use only the parts you need. But I would have this one very solution that helps me all the time, instead of implementing tons of implementations of access control that’s available for Rails. There are so many access control plugins available, I cannot even get an overview about it… but this one variation that I was looking for wasn’t there, so I chose to implement it. But as I mentioned above, my plugin won’t be available any time soon. I am already thinking about pushing it to Github, so I may get some help and share my work at the same time, but before I do so, I need to clean up and make a real project of it. Anyway, the situation now is that I do not have my own solution yet, but the projects of course cannot always wait for it. So I thought about it some more and made a decision: there always have to be both a simple and a complex solution. But which solution does my project need? Here’s some thoughts about that. Access Control Lists are a huge implementation. Using them you gain control over every single object’s permissions. You can inherit from parent objects easily, you can override the permissions for a single user though he’s still in his general user group and so forth. But the big question is here: does my project really need this? Or, which sort of projects really need this? Especially the last question came to my mind today, and it almost blew me away, because I realized that I can skip these ACLs for the more pressuring projects right away. Short answer: most public projects don’t need this sort of Access Control, but intranet applications do. Long answer is, the whole power of Access Control is only needed, if you have to be able to override permissions for single users at some point. Normal web applications that are for public use, won’t ever make use of it, because you’ll have so many users that you don’t want to control single users. Users are always grouped into roles that may be called „guest“, „normal user“, „paying user“ or such, but they will not be jailed into areas of your site, just because they belong to a special sub project or something. You will not offer special permissions if someone asks for it and you won’t need to permit use of something that is internal. A web application in your intranet will need this stuff. You will need to give a user more space than the other, or create a special repository for just one department, but this is very fine grained work that will only happen as internal stuff. It won’t happen in the public area. Sure, there will be overlaps, but some parts you will have to add to those general plugins anyway. For example I could permit the use of an object using ACLs, but I would need a additional permission system to set up something like „permit number-of-messages“ and such. So I decided for myself to not fully stick to the plan. I will look out for a solution that’s role based only for my public projects and continue work on my great ACL solution for the future. For internal/intranet projects. So if there’s anyone up for some work on a great new solution of ACLs in Rails, be my guest. Rails needs this very plugin. Database based, role independent, anything to anyone. But it’s still a hard bit of work.