[kforge-dev] access control

Rufus Pollock rufus.pollock at okfn.org
Fri Jan 13 14:41:55 UTC 2006


John Bywater wrote:
> [written to clarify my own understanding - I've been reworking the code 
> and I think I've worked it out :-)]
> 
> So, after a discussion today [now yesterday] regarding access control 
> between Rufus and I, I thought I'd try to write a narrative of the 
> access control scenario based on Rufus's design.
> 
> Plot summary (indents mean 'sub-plot'). -
> 
> - log in person
> - browse pages
>   - make request
>   - handle request
>      - authorise person for action on object
>         - check system-wide role permissions
>         - if project view: check project role for permissions
>      - take (or refuse) action on object
> 
> 
> A person logins in with the intention of taking an action against a 
> domain object. -
> 
> This creates a session, which is available as "self.session" on all kui 
> views. (If session isn't True, then there isn't a logged in user for the 
> request. A reference to the person is "self.session.person" on all kui 
> views.)

We might want to extend this to the non-kui views (i.e. to the project 
view where we access subversion, trac etc) but I think this is a 
secondary issue. For more information on this see:
   kforge.apache.*
In particular:
   * kforge.apache.modpython
   * kforge.apache.urlpermission

> 
> A person browses various pages of the system. -
> 
> (How can the system control actions taken by people on the system's 
> domain objects?)
> 
> In general, we want to control access to domain objects by considering 
> the action to be taken, the person requesting the action, and the object 
> (domain object or domain object class) that will receive the action.

nod. this is RBAC with the added assumption that all objects of interest 
are domain objects. At present this isn't true. Application subsystems 
such as trac, svn etc (can anyone think of a better name) do not 
correspond to any domain object at present yet we wish to control access 
to them.

> As a policy, we want to deny action, unless the person who requests the 
> action has sufficient permission.

yes.

> So we also want to have permissions, which allow an action to be taken 
> on a particular set of protected domain objects.
> 
> We want to grant permissions to roles, and associate people with roles. 
> We want to say that a person has a particular permission if any of the 
> roles they are associated with has that permission.

yes

> We want to protect domain objects. We want to protect domain objects 
> with protection objects. We want a protection object to be responsible 
> for knowing about the domain objects it protects, and we want a 
> protection object to be capable of reporting whether it protects an 
> object (domain object or domain object class) or not.

It could be the other way round: i.e. a domain object knows what its 
assoicated protection object is. I don't think this is an important 
distinction though (we're just inverting control)

> So, in general, and at first, we can associate a person directly with a 
> role, and attempt to authorise access by checking whether an acting 
> person's role has permission (for the requested action to be taken on 
> the object that will receive the action). This direct association of a 
> person with a role could be known as a person's "system role".)

Yes. SYSTEM ROLE

> Secondly, by providing memberships of projects to people, and 
> associating each membership with a role, we can associate a person with 
> more than one role.

or rather, depending on the context (the project), they have another 
'project' role. PROJECT ROLE

> Additionally, by creating an administration project with special 
> administration services, controlled access to administration features 
> can be provided.

This administration project can also provide a way of assigning system 
roles (your role in the administration project is your system role). 
This is the way things are currently done. This does have the 
disadvantage of being slightly confusing since it using a 'project' role 
(on the administration project) to determine a 'system' role

> At this point, there are two rather underdesigned concerns:
> 
> Firstly, there is a question concerning how a protection object knows of 
> the objects that it protects. Or, perhaps better, there is a question 
> concerning how a protection object records the set of domain objects it 
> protects.

In the current implementation this is determined by the (rather hacky) 
function:

kforge.dom.accesscontrol.ProtectionObject.getAssociatedProtectionObjectName

> Secondly, there is a question concerning the composition of permissions 
> granted by the different associations. A system role seems to pertains 
> to all the objects within the system. A project role seems to pertain to 
> all the objects within a project in the system. An administration 
> project role seems to pertain to all the objects that are operated on by 
> the services of the administration, so this might mean all the objects 
> within the system, according to the technical capabilities of the 
> administration project services.

And some objects are in both contexts at the same time. For example 
consider 'Project'. If we are in the context of project X and person P 
is admin of project X then, for example, it would be natural for P to 
have update rights on that project.

But we also have 'Project' object for the system in general (where there 
is no project context). Here we might imagine that it is only if person 
P is a **system** administrator that they have update rights.

> 
> A person's browser makes a request on the servier. -
> 
> Let's say that the requests made whilst browsing will be handled with 
> request handlers. In KForge, request handlers are methods on kui view 
> objects. The handler is responsible for initiating the action to be 
> taken in response to the request. The handler is also responsible for 
> having, in the terms of the access control system, a name for the action 
> it takes.

agree

> It should be noted that we can't prevent direct access in the code to 
> the domain model. So we must require that request handlers cooperate 
> with the access control system by asking it for proper permission before 
> acting.

yes (and that's as it should be: if you have direct access to the 
command or domain layer you are already super-super user)

> A request handler is also responsible for knowing, again in the terms of 
> the access control system, what domain objects it acts on.

yes. This might be a moment where protection object is more useful than 
the term domain object. It is up to the request handler to work out what 
protection object is relevant to the action it is trying to take

> 
> A handler requests authorisation for a person to act on an object. -
> 
> The handler knows: the acting person (as "self.session.person"), the 
> action (as "self.actionName"), and the object (domain object or domain 
> object class) to receive the action.
> 
> Therefore it must be on this basis that authorisation to act is 
> requested. And it may be that a handler makes a series of authorisation 
> requests to the access control system.
> 
> A handler may seek several authorisations, e.g. to read a project, to 
> read members of a project, and to create a member of that project.
> 
> Therefore, it seems that a handler wants to ask an access controller 
> whether a person has permission to take a named action on an object. 
> Additionally, because of the project-membership-role-permissions 
> feature, it would seem that a request handler is obliged to tell the 
> access controller whether the handler is part of a project view, and if 
> so which project is being viewed.

yes

> I suggest the following method:
> 
> AccessController.authorise(person, actionName, object, project=None)

yes. very similar to existing:

kforge.command.accesscontrol.HasPermission(person, permission,
                                            project=None)

where permission is the aggregation of a protectionObject and a 
permissionType (action)

> The authorise method: firstly examines the system wide role (iterating 
> through permissions to see whether a permission exists for that 
> actionName, and if so, whether that permission's protection object 
> protects the object; and secondly, if no permission has been found so 
> far and there is a project, examines the project role for a permission.
> 
> 
> Access is allowed. -
> 
> Handler takes action on object. Respond normally.
> 
> 
> Access is denied. -
> 
> Log details of failure. Respond with redirect to "permission denied" page.

You also want to take account of the use case where a particular option 
is only provided if a user has sufficient privileges (though still 
checking when an action is taken that it is allowed -- o/w you can be 
easily hacked). For example at present you are only presented with the 
edit/delete buttons on the members page if you are a project administrator.

Regards,

Rufus




More information about the kforge-dev mailing list