Personal tools
You are here: Home Products Plone Roadmap #45: Security Domains
Document Actions

#45: Security Domains

Contents
  1. Motivation
  2. Proposal
  3. Implementation
by Matt Hamilton last modified June 11, 2006 - 00:21
Proposed by
matth
Proposal type
State
rejected

Motivation

Security is split into 3 separate parts (often called the 3 A's):

  • Authentication - this is proving the user is who they claim to be
  • Authorisation - this is working out what the user is allowed to do
  • Audit - this is recording what the user does

Currently most Zope User Folder implementations handle the first 2 parts (Authentication & Authorisation) together. There are many user folders out there that handle remote centralised authentication (SMBUserFolder, LDAPUserFolder, exUserFolder). However central authorisation is generally not handled very well (This is not a unique problem to Plone, there are very few central authorisation systems out there in the commercial world). In Plone this becomes apparent when you scale systems to many thousands of users in an organisation and try and sanely handle the groups, roles and users.

Many large organisations have many different applications in different languages on different platforms that need to access the same authorisation information. E.g. both an intranet and a financial reports systems would like to know Can John Smith access accounts info for Dept. X?. Also, many organisations have information that can be used to drive these decisions stored in disparate systems. E.g. the HR system may know that John Smith is the Finance Director for Dept. X, hence it can be inferred that he should be able to access this data.

Another point about large organisations, is that data is not really owned by an individual, but by a role within that organisation. The fact a user has access to a piece of information, or that ability to modify some content is really a function of their job role within the organisation, not the fact that they created it in Plone in the first place. It creates lots of admin headache when users leave as content has to be re-assigned to other users, and people moved in and out of groups. Wouldn't it be great if that were abstracted out completely? Wouldn't it be great if the authorisation server could infer from the company HR database and the company phone book, who could do what, such that when a new person joins the organisation they automatically have the right access rights to the right data? :)

This is quite a radical change from Zope's roles-based authorisation, and is only intended for large installations where the savings in admin time and complexity outweigh the setup time. It is not envisaged that this would necessarily work out-of-the-box, as it requires external components to be setup.

Proposal

To build a system for central user authorisation. Each object would be tagged with a Security Domain. Plone would contact an external authorisation server, passing it the user id, security domain and action. The authorisation server would pass the details through a rules engine, probably consulting external data and return yes/no.

Implementation

The implementation is split into three main parts:

1) The Zope User Folder and security changes

2) The external authorisation server

3) The Plone UI work

Each piece of content will be tagged with a security domain (SD). This will be a label that associates all content with the same security domain to a single policy. The SD will be a string either represented in a path fashion e.g. /mycompany/mydept/reports/financial or as an LDAP style key/value pairs eg. o=mycompany,ou=mydept,ou=reports,ou=financial. This will be stored as a metadata attribute of the object.

The Zope User Folder and Security Changes

It is envisaged that the required changes to Zope in order to implement this functionality can be done entirely in a User Folder. It doesn't appear that we need to change the underlying security policy.

The new User Folder, SDUserFolder, will implement an allowed() method that passes the objects SD, the user ID and the action the user is making on the object (e.g. read, modify, delete, etc.) to the external authorisation server over LDAP. It will then expect a yes/no answer from the server and allow the user to perform the action as necessary.

We need to pass an action to the authorisation server. In the normal Zope security policy we have lost the information about what permission protected the method being called at this point and just have the roles that have access. So, in order to have this information, I suggest we (ab)use the roles and create roles of read, modify, delete, etc. and give these the relevant permissions. We can then pass this role to the authorisation server.

We will no longer use acquisition to get local role info. Each piece of content will explicitly be given a SD or will take it from its immediate parent.

External Authorisation Server

This will be an external server, and will not be Zope/Plone specific. It is envisaged that this will be an OpenLDAP sever with a custom backend written in either python (or maybe Lua as it is supposedly easier to embed). The backend will be responsible for a series of rules, these will be written directly in the programming language (ie. We won't write a rule language, python is easy enough to understand), and communicating with external systems e.g. HR Systems, external databases, scripts etc. The rules list will be the central place at which the security of the system can be audited. A set of rules may look like:

    dept =  hr_database.getDeptByUser(userid)
    level = hr_database.getLevelByUser(userid)

    if level == 'bigbigboss' and not sd.startswith('/company/sysadmin'):
      return True

    if sd.startswith('/company/finance') and dept == 'finance':
      if action in ['modify', 'delete'] and level == 'manager':
        return True
      elif action in ['view',]
        return True

    return False

In the case of Plone the Authorisation Server will be accessed via an AuthorisationServerTool. This tool will define the following interface:

  class IAuthorisationServer(Interface):

    def authorise(user, sd, workflow_state, action):
      """ contacts an authorisation server and checks if the 
      given user id is able to perform the specified action
      on an object with the security domain sd in the specified
      workflow_state """

Workflows

Currently, the main workflow engine used by Plone is DCWorkflow. Security is handled by manipulating the permissions on objects as they enter different workflow states.

Under the model of security domains, this will all be handled by the external authorisation server. Plone will pass the workflow state along with the security domain to the authorisation server, and it is the responsibility of the authorisation server to return whether the action should be allowed or not.

Searching

Currently the portal_catalog keeps an index, allowedRolesAndUsers, which is used when searches are performed in order to filter results to just those that the user can view. This becomes quite a complicated when there are large numbers of local roles assigned to users for content.

As each piece of content will have one and only one security domain associated with it, this is all that needs to be indexed. [ why was this good again? I thought we could just do a search for security domains the user can access, but the can't actuall get a definitive list can we? Won't we need to do a linear filter of the result set and ask the authorisation server if we can access each one? ]

Plone UI Work

To fit in with Plone, we will need to create an extra tab that replaces the sharing tab currently on Plone objects. This tab would allow the user to set the SD of the object. Plone may enquire from the authorisation server a list of SDs that the user has permission to access, and so could pre-populate a drop-down box with relevant entries.


For any issues with the web site functionality, please file a ticket.

Please consult the policy on plone.org content if you want your content published on this site.

Servers and hosting by