Glad You're Ready. Let's Get Started!

Let us know how we can contact you.

Thank you!

We'll respond shortly.

  • Blog Navigation
Access Control & Permissions in Rails

Access Control is a simple idea. We want company employees to be able to delete inappropriate content; but random Users cannot. Here I propose one way to implement Access Control that has the particular advantage of being very general, very concise, and unlikely to be violated. I call it RESTful Access Control.

What is RESTful Access Control?

When we model RESTfully the Application Interface (i.e., the HTTP interface), we construe Resources as responding to a simple set of Verbs: Get, Put, Post, Delete. To the extent that our entire application is designed this way, we can Control all Access to our Application with perfect granularity: as being a set of Permissions to perform these four Verbs on a corresponding Resource. Let’s start with an example.

Suppose a User can add Members to a Group. How do we determine if this or that User can create a Membership? This logic doesn’t belong in the controller — call me a prig, but Business Logic belongs in the Model. Anything else is unbecoming. Therefore, we have a Controller like:

class MembershipsController < ApplicationController
  before_filter :load_group

  def create
    membership =[:membership])
    raise SecurityTransgression unless current_user.can_create?(membership)

  def load_group
    @group = Group.find(params[:group_id])

Let’s implement the can_create? method. Despite the above Formulaic code, the User Class isn’t really the proper place for the Logic: different kinds of resources are likely to have different rules. Thus, we implement the Logic in the Model being created:

class Membership < ActiveRecord::Base
  def can_be_created_by?(user)

I call the above “the Passive Voice.” I prefer, for various reasons, to use the “Active Voice”, and therefore we implement a simple Proxy in the User Class:

class User < ActiveRecord::Base
  def can_create?(resource)

Of course, this “Active Voice” implementation requires that we follow the Null Object Pattern for Users who are not Logged In, otherwise we’ll produce Errors when we ask if a Logged Out User has Permission to do something:

class AnonymousUser < User

Why we Always Create An Instance Before Checking Permission

In our Controller Action above, we first build an instance of a Model in memory, then ask for Permission.

membership =[:membership])
raise SecurityTransgression unless current_user.can_create?(membership)

But why even create the Model in memory it shall not be persisted? Well, for some advanced Access Control Rules, we need all of the data available to an Instance in order to proceed. Suppose, for example, that only the Owner of a Group can create Memberships. The simplest way to enforce this rule is to reference the Group Owner in the can_be_created_by? method:

class Membership
  belongs_to :group

  def can_be_created_by?(user)
    group.owner == user

Similarly, can_be_destroyed_by?, can_be_updated_by?, and can_be_read_by? all must be instance methods. This provides the maximum flexibility and a consistent Interface.

This is a robust Pattern for Access Control. It extends brilliantly to User Roles:

def can_be_destroyed_by?(user)
  user.admin? or ...

Even a per-user Access Control scheme where we grant individual Users permission to manipulate individual objects can elegantly fit in. Consider something like the following:

class Permission
  belongs_to :user
  belongs_to :resource, :polymorphic => true

class CreatePermission < Permission

class Membership
  has_many :create_permissions, :as => :resource

  def can_be_created_by?(user)

Handling Access Control in the Views

Access Control has View consequences as well. For example, we shouldn’t show a destroy button if the User lacks permission to perform that Action. Given the above implementation, this is simple enough:

 <%= link_to_unless current_user.can_destroy?(resource), 'destroy', ... %>

Why Exceptions?

Above, I’ve proposed using Exceptions to handle Security Transgressions. (At Pivotal, we call these Exceptions SecurityTransgressions because it has a more romantic air than the banal AccessDenied). Normally, these Transgressions cannot happen: in your Templates you will not even display links to modify an object if the User lacks Permission. So Transgressions occur only when a User is fiddling about with nefarious intent. So we can handle misbehavior consistently across the site, by (for example) rendering a HTTP 403 Forbidden Response. Exceptions are a neat way to do this, because Rails gives us a systematic way to handle exceptions with rescue_action:

 class SecurityTransgression < StandardError; end

 def create
   raise SecurityTransgression unless ...

class ApplicationController < ActionController::Base
  def rescue_action(e)
    case e
    when SecurityTransgression
      head :forbidden

Ensuring Programmers Remember to do Access Control And How to Avoid Over-Engineering

The biggest danger with Access Control rules is the possibility that a careless Programmer might forget to implement them. Having a consistent, terse pattern for Access Control goes some way towards mitigating this problem. When all Access Control is as simple as adding a can_create? check to your Actions, Access Control is unlikely to be overlooked.

The Second biggest danger in Access Control is over-engineering. Suppose we want to enforce Access Control logic. Rails gives us some tools to do this. Well, Rails gives us just enough rope to hang ourselves. There are some serious disadvantages to the approach I am going to propose now, but we’ll get to that shortly.

Rails has something called an Around Filter. An Around Filter, like a Before and After Filter, is a Filter applied to every Action. But this Around filter is like the Heavenly Union of the Before and After Filters: both great tasting and less filling, it can do work before and after invoking the Action.

class ApplicationController
  around_filter :ensure_permission_to_create, :only => :create

  def ensure_permission_to_create
    class_name = ModelsController.to_s.demodulize.gsub(/Controller$/,'').singularize
param_name = class_name.downcase
    instance_variable_name = "@#{class_name.downcase}"

    instance_variable_set instance_variable_name,[param_name])
    if current_user.can_create?(instance_variable_get instance_variable_name)
      yield # the create acction is invoked here.
      head :forbidden

Whew. In the above implementation, control is yielded to the Action only if the User has permission. The instance of the Model is also built for us automatically; so, our Formulaic create Action becomes:

def create

Very DRY, But this is, again, just enough rope to hang ourselves with. Our Controllers need to be named exactly right, our parameters without an inconsistency, and so forth. This is not a problem in the World of Forms, but in Reality it may require some coding contortions. The tricky metaprogramming and impertinent assumptions in ensure_permision... only get nastier when we want to make a Nested Resource, and build our Model using a proxy (as in the previous example:[:membership])). Finally, where we have Controllers that do not map directly to ActiveRecords, we would need to introduce a Model layer that responded to the Interface defined in ensure_permission... We often want to do this, but not always. Being forced to might suck. So I offer this design strategy with much caution.

The Exception based approach, while a bit more verbose, is battle-tested and works in Practice. In any case, pushing the logic to the Model with can_be_created_by? will certainly work, regardless of whether you take the Around Filter approach or the Exception-Based one.

  1. One issue I have run into: 401 is not always the most
    appropriate response code for security transgressions. Returning a 401 has the effect of confirming that the resource
    does, in fact, exist. In many situations this is fine, but if
    the URIs include any human interpretable information it might be

    We have solved this problem having a #visible_to?(user) method on
    models. With that you can easily implement “permit” function that
    will return 404 if you try to do something with a resource that you
    are not allowed to know exists, or a 401 if you try to do something
    you are not allowed to on a resource that you are allowed to know

  2. Daniel Neighman says:

    This is really a great idea. I have been starting down this road by using in my controllers

    resource.destroyable?( current_user )
    resource.readable?( current_user )

    and raiseing Exceptions on those, but I think I really like this method a lot more.

    Great post. Thanx

  3. Dr Nic says:

    Hobo ( has a nice inbuilt authorisation concept.

    On each model, you can specify access methods, e.g. (from myconfplan code for Conference model)

      def creatable_by?(creator)
        !creator.guest? && creator == user
      def updatable_by?(updater, new)
        !updater.guest? && updater == user and same_fields?(new, :user)
      def deletable_by?(deleter)
        !deleter.guest? && deleter == user
      def viewable_by?(viewer, field)
        viewer == user || conference_sessions.count > 0

    Then, all the widgets and all the views can access helper methods to query “can current_user see/edit/delete this object?”

    Its a killer feature of hobo, imo.

  4. Vrensk says:

    Interesting article, and a very nice pattern for doing this. The resultant code looks really good. But call me_ a prig, for while I agree with you that the can-x don’t belong in the controllers, I don’t think that they should be called from the controllers either. In my opinion, it is the _model’s responsibility to ensure that model-space modifications are done in a consistent way. So I’d rather make the controllers even skinnier and the models fatter, and have the controllers just call create-this-or-that-if-i-am-allowed.

    That being said, I haven’t done so in practice yet, because it felt too complicated. But if I moved your clever build-first, test-after pattern to the model, perhaps it wouldn’t be so hard after all.

    Thanks for an interesting article!

  5. Nick Kallen says:

    Vrensk: your approach sounds promising. Let me know how it works out. I’m skeptical though. Consider,

    model.read_as(current_user) # well, I dunno about this one!

    The asymmetry of the last indicates to me that the Controller is the proper layer for this. After all, it’s really only the controller that has a concept of a current_user. Models are timeless (users are not current, they just are).

  6. David Parker says:

    @Nick Kallen,

    Good article. I’m just getting into Rails a bit and I’ve been looking for a good access control system. I’m already using RESTful authentication, so your solution seems to fit right in. By any chance, can I get some of your source code? or do you know of any location where I can get some (at least for learning more)? Thanks for the article!

  7. Rabbit says:

    I’m a heavy object thinker, and I gotta say, I dig your style. Recognizing and labeling a distinction between “active” and “passive” voices blew my mind.

    Let’s implement the can_create? method. Despite the above Formulaic code, the User Class isn’t really the proper place for the Logic: different kinds of resources are likely to have different rules. Thus, we implement the Logic in the Model being created:

    I like your stance on “who should do what,” because that’s a problem I’ve often encountered. Does the user add himself to the group or does the group add the user to itself?

    Correct me if I’m wrong but it sounds like you’re saying that the object to be altered should be responsible for deciding whether it can be altered. Is that accurate?

    I have a question though… regarding the active voice. While I love the sentence-like nature of it (I often write code like this – I love asking questions in Ruby!) it feels like it’s more tightly coupled that it “should” be. Class User knows that class Group has a “can be created by(user)” method.

    How do you feel about that? Is inevitable? Am I worrying too much? (I hope that’s the case…)

  8. Rabbit says:

    What about the index method? How can a user or resource know whether the user has access to something like Object.find(:all)?

    Checking for instance-level access is easy (as shown above in a number of ways), but how do you check for access to the class at all?

  9. Rabbit says:

    Crazy. Your comment appeared as soon as I posted mine.

    Beautiful code doesn’t ignore rules, it makes up its own rules.

    Agreed. In my experience there are a lot of people that don’t like when you don’t play by their rules. Screw them.

    The last two projects I’ve worked on have basically made it a requirement that all ActiveRecords implement #creatableby? etc. (Actually, it’s implemented in ActiveRecord::Base as def creatableby true end so you only have to override it if you need it to be more restrictive.

    I like that. I was just writing out all the “can be … by” methods and thought, this is terse. So I came up with something like…

    def has_access_to?(verb, user); ... end

    And as I was writing that I thought, I should probably put this into a module. Extending Active Record would works, too (apparently).

    Ultimately, I’ve enforced that all ActiveRecords adhere to a certain interface, namely they have these permissions rules. If that’s coupling, it’s not a bad thing.

    I like that, too. One could argue that ActionController is tightly coupled with ActionView. The argument is stupid. Coupling occurs at some point regardless what you’re programming. Hell, your keyboard is coupled to your computer; get over it. It’s knowing when and what to couple. (Know the rules, then break them.)

    I’m glad I found your blog. It’s definitely top-notch. Please keep writing. There are few programmers where I live, fewer are anything above mediocre, and still fewer have even heard of Ruby, so it’s nice when someone picks their brain and shares the findings. I consider myself an advanced beginner and I’ve been programming for six years.

  10. Rabbit says:

    Sorry to post so much, I just keep getting new ideas… What do you think of this?

    class Store < ActiveRecord::Base
      def creatable_by?(user)
        # Style one. Permissions are attributes attached to model.
        user.director? or user.manager?
        # Style two. Permissions are abstracted away from model.
        user.permissions.find_by_name('Can create stores')

    The first style is what I gather you are doing. The answer to the question comes directly from the model, from the programmer. I like it, it’s clean and it’s easy to implement. But it’s limited (not a bad thing).

    The second style allows users of the system to cherry-pick what permissions each user has, probably via an interface with check boxes (my goal). This gets away from the idea of roles as concrete programmatic constructs. Instead, roles (e.g. director, manager) are defined by convention. All directors have these permissions, all managers have these permissions. This guy’s a doofus so give him very few permissions.

    You could even emulate the first style by doing something like:

    permissions.find_by_name('User is a manager')

    I think that was part of my confusion, too. You sub-classed Permission into CreatePermission (I assume to mean the “create” verb, implying there would be an EditablePermission and DestroyablePermission as well), but the “creatable by?” code used methods attached to the user; methods that are probably hard-coded. I was trying to do both; abstract the implementation of whether or not someone has permission and trying to write the implementation.

    Whew! It’s time for bed. Thanks for taking the time to comment, Nick. I appreciate it. Have a good night.

  11. Nate says:

    I’ve been playing with implementing a role/permission based system similar to this but I can’t seem to wrap my head around everything that is going on and how it all relates in the model. Do you know of any tutorials that I can look into some more that may help?

    I’ve found quite a few tutorials but they are VERY outdated for rails 2.0 and RESTful design.

  12. Nate says:

    I’ve been playing with implementing a role/permission based system similar to this but I can’t seem to wrap my head around everything that is going on and how it all relates in the model. Do you know of any tutorials that I can look into some more that may help?

    I’ve found quite a few tutorials but they are VERY outdated for rails 2.0 and RESTful design.

  13. Carlos S says:

    I liked your solution. I am stuck at one thing, otherwise this works great..
    How do you verify current_user? I am taking current_user using session[:user] data. However, if no user is logged in then I get nil object. I want this page to be accessible by everyone, but only certain parts of page will have this access rule.

  14. Joseph Palermo says:


    Nick mentioned `AnonymousUser` briefly above. We have current_user always set to either the currently logged in user, or to a singleton instance of `AnonymousUser`. That way you never have to worry about calling one of the methods on `nil`.

  15. Carlos S says:

    Thanks Joseph..!
    I used ternary operator for this: @currentuser? call_method : false .

    I have nested resources in my application – (topic has_many items).
    And on my show topic page I have a link to ‘Add new item’. I would like to show this link only to users with certain roles. However, I am not able to pass this resource (item) as it has not been initialized.
    So how can I call method like: @currentuser.can_create?(item) from my show topic page. I am initializing resource objects within the controller, but how can I initialize these from my view? Do I need to? Any clues?


  16. Joseph Palermo says:

    The new record case the ugliest part. The only way to keep within this security model is to actually build a new object, then do the security check on it. So in the new case, you always build an object that you are never going to save.

    So you end up with something like this in your view code:

    link_to(new_item_path) if current_user.can_create?(

  17. Carlos S says:

    Sorry, but I am beginner in the programming world. What should this subclass of User return? How do I implement this as a null object? Wouldn’t this subclass get all the methods of User class?

    This is digression from main topic. But I will really appreciate if someone could explain this to me.


  18. Joseph Palermo says:

    We do actually subclass User, but you wouldn’t have to. It hasn’t caused any problems for us having User methods on AnonymousUser since it has no data.

    You’ll need some way of distinguishing AnonymousUser’s from users, you could just use is_a? or you could put an anonymous? method that returns false for User and true for AnonymousUser.

    We also override id on AnonymousUser to return nil, that way you don’t end up accidentally using it to create associated objects.

  19. Carlos S says:

    Thanks a lot Joseph..

    I am still struggling to do this. Here is my message on ruby-form’s RoR list:

    I don’t want to eat up space over here on a unrelated issue.

  20. Carlos S says:


    Your following suggestion doesn’t work for me:

      link_to(new_item_path) if current_user.can_create?( 

    When the authorization goes to items model for can_be_created_by?(user), the check on self.topic.creator fails for nil.creator.
    In my application, only topic creator can add new items and then assign it to someone. I could do this by passing topic id or topic object, however this breaks the consistency in interface.


  21. Carlos S says:

    And it works for the view (link_to).
    However, it fails when it goes new/create method in controller.

  22. Carlos S says:

    So embarrassing.. It worked..

    In the new method – used and then called access control method.
    In the create method: created instance using params and had to explicitly add @item.topic = Topic.find(params[:topic_id])


  23. Joseph Palermo says:

    Glad you got it figured out.

    You should still be able to use the topic to create your item in the create method without setting it explicitly.[:item])

  24. Carlos S says:


    I am setting current user as anonymous user if there is no user info in the session variable.
    def current_user_and_role
    if session[:user].nil?
    # used null object pattern
    @currentuser =
    @currentusername = ‘Unassigned’
    @currentrole = ‘anonymous’
    @currentuser = User.find(session[:user])
    @currentusername = @currentuser.username
    @currentrole =

    The problem is while using wget or curl command. This occurred while testing and in implementing functionality to generate static html archive.

    I get an error like:
    ActiveRecord::StatementInvalid (Mysql::Error: MySQL server has gone away: SHOW FIELDS FROM `users`):
    /usr/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/connection_adapters/abstract_adapter.rb:147:in `log’

    /usr/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/base.rb:2126:in `initialize’
    /app/controllers/application.rb:13:in `new’
    /app/controllers/application.rb:13:in `current_user_and_role’


    So how should I implement this to set current user to logged in or anonymous user?

  25. Daniel Draper says:

    I’m curious if your access control permissions implementation has changed since this article was written? Would love to see an update on how you’re currently doing permissions and learning from this approach if you decided to change etc.

Post a Comment

Your Information (Name required. Email address will not be displayed with comment.)

* Copy This Password *

* Type Or Paste Password Here *

Share This