Posts categorized “Authorization”.

declarative_authorization 0.4

I just pushed the decl_auth 0.4 gem to gemcutter.

Major changes since the 0.3 release:

  • Improved DSL: allow nesting of has_many associations for if_permitted_to and if_attribute:

    has_permission_on :companies, :to => :read do
      if_attribute :branches => { 
          :manager => { :last_name => is { user.last_name } } }
      if_permitted_to :read, :branches
    end
  • Simplified controller authorization for RESTful controllers with filter_resource_access. Instead of multiple filter_access_to statements, one line is often sufficient:

    class BranchController < ApplicationController
      filter_resource_access :nested_in => :companies
    end
  • Controller namespace handling.  Now, the decl_auth context in controllers is prefixed by the underscored namespace by default. Thanks for all those implementation suggestions in the Github forks.

  • Improved STI handling by allowing to explicitly define the model’s decl_auth context.  Just override AModel.decl_auth_context.

  • Test helper to test authorization rules, e.g.

    with_user a_normal_user do
      should_not_be_allowed_to :update, :conferences
      should_not_be_allowed_to :read, an_unpublished_conference
      should_be_allowed_to :read, a_published_conference
    end
  • permitted_to?/! on model level. You may now use those methods in models as you are used to from controllers and views.

  • Switched to gemcutter for gem distribution.

  • Change support in the development support backend (I’ll write a separate Blog post on decl_auth change support soon)

And lots of smaller fixes: full change log.

Releasing declarative_authorization 0.3

I just pushed the 0.3 release for declarative_authorization to github.  declarative_authorization helps Rails developers to implement authorization in a declarative manner, cleanly separating authorization rules from application code and reusing the same policy for access control in model, view and controller.

So, what’s new in 0.3? Apart from smaller fixes and improvements, a few major items:

  • Gemified the plugin
  • Allow to globally enable model security by calling ActiveRecord::Base.using_access_control
  • New operator intersects_with
  • AND’ing attribute conditions in has_permission_to blocks

Also, helping you in handling complex policies and using declarative_authorization correctly, a Rails Engines-based GUI has been implemented, with graphical policy browser and usage analyzer. The full changelog.

Using Your Authorization Framework Correctly?

Many projects employ authorization frameworks to control and enforce permissions. Custom-built or off-the-shelf, how sure are you that your projects are using the framework in the correct way? And have authorization checks at all the necessary locations in your code base?

One way, of course, is code review. Have knowledgeable people point out the mistakes by looking over the code. Complete code reviews may be prohibitively expensive, though. Being a cross-cutting concern, you need to look at a lot of code for authorization aspects.

Penetration tests: definitely necessary. Still, penetration testing isn’t likely to find a one-time error in the usage of the authorization framework. Achieving a high coverage is very expensive.

So, what about authorization-focussed static analysis? It would definitely improve code review efficiency. Commercial static analysis tools still primarily look for programming errors, though. As authorization checks are typically employed in a structured manner, they can be easily analyzed if the framework is known well by static analysis rule developers.

For Rails apps, our Rails authorization plugin declarative_authorization comes with  support of this kind. In the screenshot, controller authorization analysis is shown. Possible flaws are highlighted in yellow and red and the found problems are displayed in tool tips.

Authorization Usage Browser for declarative_authorization

In the demo app, the authorization usage browser reveals which actions aren’t (properly) protected by authorization checks. For example, SessionsController#create is marked red for having no authorization check. This, of course, is intentional as this action allows users to login.

The yellow coloring of ConferencesController#index shows that this action is just generally protected and authorization constraints are not enforced. Again, this is intentional because index lists conferences and conference-specific authorization is checked at database query time. If other actions were marked in this way, the developer could easily make out the mistakes and correct potentionally highly critical bugs.

Try it out in the declarative_authorization demo application! And leave a note on whether this is of use to you.

For now, the tool analyzes authorization on controller level.  As declarative_authorization also comes with authorization for the model level and database query rewriting, a next step will be looking at issues in those areas as well.

Graphically Browse Your Authorization Rules

It certainly helps to have the authorization rules in your Rails app defined in a clear DSL, such as the one offered by declarative_authorization. Still, with anything more than a few roles and models (let’s not even think about 200 models), it can be hard to maintain a good view of the whole rules set.

So, how about a graphical browser of your authorization rules?  In particular inheritance between roles and privileges – and consequences thereof – may be much easier to grasp in a graphical way. This is how it looks in the declarative_authorization demo application:

Authorization Rules Browser

Roles are shown in colored ovals and are connected to privileges in the context boxes. Inheritance links between roles and privileges are displayed in black, with unfilled arrows. Filled circles on role-privilege links show additional rules that apply.

You can filter to dig deeper into the rules and limit the view to certain roles or contexts. Also, you can decide to only display those privileges that are explicitly stated in the authorization configuration or all privileges that the roles possess.

If you are interested, give it a try. Either in the declarative_authorization demo application or in your own application. The declarative_authorization README tells you the one simple step to get it started. This feature requires graphviz for graph generation and Rails 2.3 for its Engine support.

On the long run, we’d like to integrate multiple abstraction levels for different viewing audiences and we might even add authorization rule editing capabilities.

What do you think? Does this help you as a developer or in discussions with non-technical customers about authorization?

Authorization for 90 Controllers, 200 Models (and Counting…)

One of the interesting comments on our RailsConf Europe presentation on declarative_authorization was offered by Timo Hentschel. He stated that on the Rails CRM project with 90 Controllers and 200 Models that he is working on the declarative_authorization approach was simply not viable. Projects of this size are currently not the target of our plugin, though. Currently, we focus on bringing maintainable authorization into small to medium applications. Nevertheless, it is interesting to look into Timo’s points:

  • “Role definition is for admins not developers”: It certainly depends on the project size. With small to medium apps (our primary target) admins might just be the developers. Still, our future plans include a possible move of the authorization rules to database, enabling a policy editing UI.
  • “You’d need a UI for handling the policy development”: This might be true. But without further evaluation, I am not convinced of the superior performance of a UI when compared to a readable, concise policy syntax. Policy files still provide documentation and specification for free. We will look into UIs, especially to facilitate a test-driven policy development approach, though.
  • “I can’t redeploy on every role modification”: In practice, engineering an application’s policy is certainly error prone. Missing permissions will have to be added to roles once taken into production. Changing roles on a production system isn’t optimal either, though: role-permission assignments need to be carefully checked for side effects. Thus, a QA workflow would be desirable, just as provided by a deployment cycle. I would prefer to handle missing permission assignments just like other software bugs which need to be fixed asap. Nevertheless, with the planned features (TDD, UI, policy in DB) and an integrated authorization workflow, online role modifications may be feasible. In our self-service authorization approach we would even like end users to extend their permissions on their own, on a limited scope and in some environments.
  • “With 90 Controllers, the authorization policy will become unmanageably long”: This is certainly true with the current syntax. On the one hand, we will distribute rules to multiple files in order to group similar aspects. Also, currently one context is used per model. A hierarchy of contexts is planned to cut the number of specific rules and thus ease policy development and maintainability.

From Rails Security to Application Security

I’m in Berlin for RailsConf Europe currently where I’m talking together with Carsten Bormann about implementing application security in Agile development with Rails and announcing declarative_authorization.

Here is our presentation (will only really display nicely on Firefox 3, though, sorry; full window view):

Declarative Authorization

Having looked through quite a few existing Rails authorization plugins, we decided, we were in need of a different approach.  Mainly, it was the missing separation of authorization logic from business logic in the evaluated plugins that caused us to implement a new plugin, declarative_authorization.

In our declarative approach, authorization rules are grouped in a policy file, while only privileges are used inside program code to enforce restrictions. We developed for flexibility and simplicity, requiring only very simple statements in rules and program code. So instead of

class ConferenceController < ApplicationController
  access_control :DEFAULT => [:admin],
    [:index, :show]  => [...],
    [:edit, :update] => [:admin, :conference_organizer]
end

cond = permit?([:admin, :conference_organizer]) ?
           {} : {:published => true}
Conference.find(:all, :conditions => cond)

<% restrict_to [:admin, :conference_organizer] do %>
  <%= link_to 'Edit', edit_conference_path(conference) %>
<% end %>

with all the authorization logic interweaved with your code, you only need this

class ConferencesController < ApplicationController
  filter_access_to :all

  def index
    @conferences = Conference.with_permissions_to(:read)
  end
end

<%= link_to 'Edit', edit_conference_path(conference)
            if permitted_to? :edit, conference %>

And, separated in one place the authorization rules:

role :guest do
  has_permission_on :conferences, :to => :read
end

role :conference_organizer do
  has_permission_on :conferences, :to => :manage
end

So, the same rules are used in enforcing authorization in Model, View and Controller. Also, they are used for Query Rewriting to automatically constrain the retrieved records according to the authorization rules.  Thus, you just modify the rules on authorization requirement changes and you can also use the rules to talk to business owners of Agile projects.

For additional information and more examples, refer to the README and the rdoc documentation. Currently, we are using the plugin for an application with fairly complex authorization and it will be taking into production in the next iteration. So, look into it if you have authorization concerns in your application, it’s released under MIT license.

Rails Authorization Plugins

Updated 2009-05-23

There seems to be a consensus to choose AuthLogic or restful_authentication as the Rails way of securely identifying the users, at least with local user databases (in contrast to e.g. OpenID authentication). For restricting the access rights of the individual users, i.e. authorization, the situation is different with lots of alternatives. This is probably due to the varying requirements that projects have in the case of authorization. While there are lists and surveys of Rails authorization plugins, I was missing an overview that could help in the decision making process of choosing the right plugin for my specific requirements.

I tried to examine each plugin according to a few aspects.

  • Access control may be enforced on different layers, in the model, for controller actions and in views.
  • Most plugins have some user and role concept for restricting access. Authorization constraints allow more fine-grained decisions, though, by defining conditions that need to be met, probably on a context object, in order to grant access.
  • It is common to define access rules through Access Control Lists (ACL) whereby an object has a list of users or roles that are allowed to operate on the object. ACLs may increase authorization maintenance as new users or roles need to be added at multiple places. In contrast, Privileges, as known from RBAC, are a further abstraction. Thus, users or roles may possess privileges, which are, on the other hand, assigned as a requirement to operations on the objects.
  • Simplicity helps so that it is a common rule to use the least complex solution possible for a given task. While it is difficult to evaluate complexity without working in-depth with an authorization plugin, I still tried to give a rough estimate of each plugins complexity from an application developer’s point of view.

My conclusion (disclaimer: I’m the author of declarative_authorization): depending on the size of your project, you face roughly three options:

  • Go for a simple solution which most likely won’t cover all the edge cases, like role_requirement.
  • Follow a simple recipe and roll your own authorization mechanism. This way, you won’t depend on any maintainer to keep the plugin up-to-date. Also, it will be easier to modify it to your requirements.
  • If you see more complex scenarios on the horizon, say more than three roles, maybe even role hierarchies, you should seriously look into the more complex, but also more maintainable options, such as declarative_authorization.  Having all your authorization rules in one place helps greatly when the rules need to be modified.

A table of the evaluated authorization plugins, roughly sorted by activity:

Restrictions for M C V Constraints Privileges Complexity Activity
Authorization Yes Yes No Yes No medium recently
Restrictions based on pseudo natural language sentences; decisions based on role ACLs on models or model instances
declarative_authorization Yes Yes Yes Yes Yes medium recently
Declarative approach: separation of authorization logic from program code for maintainability
acl9 No Yes Yes Yes No medium recently
Access control list with simple role model allowing to bind roles to specific objects. Constraints through custom has_role methods on models.
RESTful_ACL Yes Yes Yes Yes No simple recently
Restrictions based on permission methods on models for CRUD operations; no role concept built in; seems to be restricted to CRUD controller actions
Padlock Authorization Yes Yes No Yes No medium recently
Allows for objects to have roles according to specific users.
redpill_access_control No Yes Yes No No medium recently
Uses access restrictions to controller actions for restrictions in views.
Authorize No Yes Yes No No high recently
Has a subject/trustee concept for specifying relationships regarding authorization.
role_requirement No Yes No No No simple recently
Role-based ACLs for restrictions on controller actions
ActsAsAuthorizable Yes No No Yes No medium 2008
Restrictions based on pseudo natural language sentences; decisions based on role ACLs on models or model instances
base_auth Yes Yes Yes Yes No simple 2008
User object-based restrictions on controller actions and views
Role-ful Yes No No Yes Yes medium 2008
Defines roles in the user object that can be queried through instance methods.
Easy Access Yes No No Yes Yes simple 2008
Helps defining can_be_[action]_by on the model.
Blubber No Yes No No No simple 2008
Used by defining [role]_acl methods on the controller.
acts_as_checkpoint Yes Yes No Yes No simple 2008
Role-based restrictions on controller actions; simple model restrictions through methods on models, employing associations
ActsAsPermissible Yes No No No No medium 2008
Provides the basic necessity of authorization: the model methods for assigning permissions and roles to users and retrieving the merged permissions.
acl_system2 No Yes Yes No No simple 2007
Role-based ACLs for restrictions on controller actions and in views; similar: Simple Access Control
ActiveRbac No Yes No No Yes medium 2007
Implements only the queries on model instances for access rights
access_control No Yes No No No simple 2007
Simple controller action restrictions based on Unix-style rwx ACLs
UserEngine No Yes No No Yes medium 2006
Controller/action-based privileges assigned to roles for filtering access to controller actions
ActiveAcl Yes No No Yes Yes high 2006
Complex database design to allow arbitrary user – role – privilege – object relations

Let me know if I missed important aspects of those plugins or other plugins that you like.

Authorization in Small and Medium Enterprises

Modeling authorization for workflows in Small and Medium Enterprises (SME) differs from the approach taken in large corporations. The latter employ heavy workflow management systems that are deployed by help of immense consulting resources. By contrast, typical SME need to implement fairly straight-forward workflows while preserving a good deal of flexibility that they are used to from the established informal workflows such as passing around spreadsheets.

From our experience in working with an SME to implement their workflows in a web application, modeling the authorization is a crucial factor. While information security is welcomed by the management, measures need to interfere as little as possible with the daily work. Also, domain experts tend to describe ideal workflows, which is sometimes called Process Confabulation. Frequent exceptions may be unknown to developers until late in the development cycle, despite user tests.

Therefore, we propose a new approach to access control, allowing users to decide when to extend their previously defined privileges in a controled manner. Thus, the effect of inacurate definition of process and authorization models is mitigated. This concept of “self-service” is described in detail in the German paper that I wrote together with Carsten Bormann, “Berechtigungsmodellierung im Geschäftsprozessmanagement von KMU” and presented at the DACH Security conference in Berlin.