Sakai 2.1 Access Control and Inheritence thoughts

In response to a discussion on the framework@collab.sakaiproject list.

The problem

Consider a course directory

/courses/ee100/
Read-Write: Instructors
Read: Section-A
Read: Section-B

And we want to give read-write to a group called "Instructors" and give read two groups called "Section-A" and "Section-B"

When we make subdirectories in general we want them to inherit ACL from the course so

/courses/ee100/handouts/
/courses/ee100/files/
/courses/ee100/asssignments/

All have the same permission as course - they simply inherit the three ACLs above...

However in assignments we want to make two subfolders and make them have permission only to each folder for each section. But instructors still have permission to everything.

This is the desired outcome:

/courses/ee100/assignments/A/
Read-Write: Instructors
Read: Section-A

/courses/ee100/assignments/B/
Read-Write: Instructors
Read: Section-B

But since we inherit permission from above, these permission statements are redundant because all three groups already have permission at the /course/ee100 level. So while we thought we were locking these folders down - they are indeed wide-open to all.

One solution is to come up with a simple "Block from above" "magic mark". With the magic mark capability the ACL's look as follows:

/courses/ee100/assignments/A/
Block-from-above: True
Read-Write: Instructors
Read: Section-A

/courses/ee100/assignments/B/
Block-from-above: True
Read-Write: Instructors
Read: Section-B

This effectively means that you must turn off all inherited ACLs and explicitly re-add all the groups to these new folders.

If a new group called Guest-Inst is added at the top level,

/courses/ee100/
Read-Write: Instructors
Read-Write: Guest-Inst
Read: Section-A
Read: Section-B

They have no permission to any of the objects marked "Block-from- above" unless someone goes through and adds the ACL to all of those objects.

An alternative approach is to make two "magic flags". One marks an access control as "blockable" and another which blocks only those access controls which are marked as blockable...

/courses/ee100/
Read-Write: Instructors
Read : Section-A (blockable)
Read : Section-B  (blockable)
/courses/ee100/assignments/A/
Block-Blockable: True
Read: Section-A
/courses/ee100/assignments/B/
Block-Blockable: True
Read: Section-B

Now the Instructor group has power over all because it is "not blockable". Also we can add new groups which are either blockable or not blockable:

/courses/ee100/
Read-Write: Instructors
Read-Write: Guest-Inst
Read : Section-A (blockable)
Read : Section-B  (blockable)
Read : Section-C (blockable)

And there is no need to update any objects - the new guest instructors inherit power everywhere because their power is not blockable. Section-C sees everything except those things with Block- blockable.

This second approach requires more stuff - but avoids running around and patching ACLs as permissions get changed. The second approach also does not require the copying of the non-blockable ACL's to the sub-folders with reduces ACL scope.

So - the question is which of the two approaches is "better". Better is some combination of "better for the user" and "better for the system implementor".

Also - is there any example of a real working production system like AFS, Xythos, JSR-170, Active Directory, etc etc that already solves this nicely and has precise syntax to express these issues?

It is also completely cool to propose a new approach overall. Such as use XACML to express it all.

A design for a solution

Primitives

Grants

A grant is a grant of permission to some particular group. It applies to some particular object in the hierarchy.

Permissions

Permissions here are "sets of permissions", what Sakai 2.0 calls "roles". They are a potentially site-specific bundle of authorizations. The kinds of permissions one might have might be:

  • Read
  • Write
  • Grant permissions (ability to grant and revoke read and write permissions)
  • Administer (ability to grant and revoke Grant permissions and administer permission)

These roles are primitives sufficient to implement drop boxes (write only), read only, priviliged users able to administer a resource (grant permission) and super users over a resource.

Inherit-from-parent

Any given object in the hierarchy can have the inherit-from-parent flag. If this flag is true, then the grants to the parent object apply to this object in addition to any other grants specific to this object.

Groups

Groups are scoped to a course. That is, a course might have Instructors, students in Section A, students in Section B, and Guest Instructors. The Section A for this course will be different from the Section A for some other course.

Representing the examples

The grant on the parent directory

/courses/ee100/
Read-Write: Instructors
Read: Section-A
Read: Section-B

Handouts inherits from the parent

/courses/ee100/handouts/
Inherit-from-parent: true

Which at the moment is the same as

/courses/ee100/handouts/
Read-Write: Instructors
Read: Section-A
Read: Section-B

but has the behaviour of updating whenever the grants on /courses/ee100/ changes (presumably by representing the grants as a reference back to the parent's grants).

Not inheriting

To implement the section-specific folders, we opt out of inheritence of grants and re-specify explicitly the grants:

/courses/ee100/assignments/A/
inherit-from-above: false
Read-Write: Instructors
Read: Section-A

/courses/ee100/assignments/B/
inherit-from-above: false
Read-Write: Instructors
Read: Section-B

I think it's cleaner to represent this in terms of whether we inherit or not rather than rather we block or not. block=false is a double negative.

Adding a grant

Now we turn to the use case of adding the guest professors.

If a grant to another group called Guest-Inst is added at the top level,

/courses/ee100/
Read-Write: Instructors
Read-Write: Guest-Inst
Read: Section-A
Read: Section-B

then that grant will apply to handouts, which inherits from its parent:

/courses/ee100/handouts/
Inherit-from-parent: true

but it will not apply to the assignments folders, which do not inherit from their parent:

/courses/ee100/assignments/A/
inherit-from-above: false
Read-Write: Instructors
Read: Section-A

/courses/ee100/assignments/B/
inherit-from-above: false
Read-Write: Instructors
Read: Section-B

What to do?

I think the grant adding UI / API needs to be aware of this issue and allow the granter to specify whether to apply the grant to children that do not inherit from the parent, something like

This permission grant will apply to the selected resource and children which inherit 
grants from it.  Do you also want to explicitly add this grant to children which do 
not automatically inherit permissions from this resource?
[ ] No.  Allow this grant to inherit normally.
[x] Yes.  Apply this permission to all children of this resource, 
    including those that do not normally inherit all permissions from this resource.

Selecting yes would cause the code to traverse the tree seeking nodes with "inherit-from-above: false" and explicitly add the grant to those nodes.

This supports the "adding the guest instructors" use case.

Selecting no supports the "adding a new section" use case, where we'd like to add a section C and have those permissions not apply to /courses/ee100/assignments/A/ and /courses/ee100/assignments/B/ .

Revoking a grant

When we revoke a grant, the API / UI again needs to provide the opportunity to only remove the grant from the specific resource and those that inherit permissions from it, versus explicitly traversing the tree to remove the grant from resources in the tree on which it has been explicitly granted.

Suppose we want to remove the Guest Inst permissions:

Revoking Guest Inst's permissions

Revoking "Guest Inst"'s permissions on /courses/ee100/ .
Guest Inst had permissions "Read" and "Write". This will also revoke these permission whereever they are inherited in the children of /courses/ee100/.
Guest Inst also has these permissions explicitly granted on children of /courses/ee100/ :

Child Permissions granted
/courses/ee100/assignments/A/ Read, Write
/courses/ee100/assignments/A/ Read, Write

( Just revoke permission on /courses/ee100/ )
( Revoke permission on /courses/ee100/ and also revoke the permissions that were explicitly granted on the children. )

User interface issues

The permissions view for any given resource needs to show both explicit grants for the resource and inherited permissions.

Permissions view for /courses/ee100/assignments/A/

Permissions for /courses/ee100/handouts

Permissions inherited from /courses/ee100/ ( Stop inheriting )

role Read Wite Grant Permissions Administer
Instructors Yes Yes No No
Section-A Yes No No No
Section-B Yes No No No

Permissions explicitly granted on this resource:
None
Grant a permission on this resource

Permissions for /courses/ee100/assignments/a

Not inheriting permissions from parent. ( View grants that could be inherited )

Permissions explicitly granted on this resource:

role Read Wite Grant Permissions Administer
Instructors Yes Yes No No
Section-A Yes No No No

Labels

 
(None)