Introduction into the ACL structures

The new ACL system being introduced into MidCOM provides ground-breaking changes to the Midgard World. This article describes the structure of the ACL in detail, as the mRFC 15 is very confusing at that point, I admit that. Before I update the mRFC I decided to write a bunch of articles covering one aspect at a time.

Attention: The contents of this article has been moved to the MidCOM API documents (official URL pending, current snapshot is available).

Privileges in general

A privilege record consists of three informations:

So much for this, I already see you looking with big eyes at me. Lets take this apart now. The most immediate question is probably Where the hell do I now assign privileges, and what happens then? To answer this questions we have to look at the privilege merging chain.

How are privileges read and merged

First, you have to understand, that there are actually three disctinct sources where a privilege comes from: The systemwide defaults, the currently authenticated user and the content object which is being operated on. We'll look into this distinction first, before we get on to the order in which they are merged.

Systemwide default privileges

This is analogous to the MidCOM default configuration, they are taken into account globally to each and every check wether a privilege is granted. Whenever a privilege is defined, there is also a default value (either ALLOW or DENY) assigned to it. They serve as a basis for all privilege sets and ensure, that there is a value set for all privileges.

These defaults are defined by the MidCOM core and the components respectivly and are very restrictive, basically granting read-only access to all non sensitive information.

Currently, there is no way to influence these privileges unless you are a developer and writing new components.

User / Group specific privileges

This kind of privileges are rights, assigned directly to a user. Similar to the systemwide defaults, they too apply to any operation done by the user / group respectivly throughout the system. The magic assignee SELF is used to denote such privileges, which can obviously only be assigned to users or groups. These privileges are loaded at the time of user authentication only.

You should use these privileges carefully, due to their global nature. If you assign the privilege midgard:delete to a user, this means that the user can now delete all objects he can read, unless there are again restricting privileges set to content objects.

Content object privileges

This is the kind of privilege that will be used most often. They are accociated with any content object in the system, and are read on every access to a content object. As you can see in the introduction, you have the most flexibility here.

The basic idea is, that you can assign privileges based on the combination of users/groups and content objects. In other words, you can say The user x has the privilege midgard:update for this object (and its decendants) only. This works with (virtual) groups as well.

The possible assignees here are either a user, a group or the magic assignee EVERYONE, as outlined above.

Be aware, that Midgard Persons and Groups count as content object when loaded from the database in a tool like net.nemein.personell, as the groups are not used for authentication but for regular site operation there. Therefore, the SELF privileges mentioned above are not taken into account when determining the content object privileges!

Privilege merging

This is, where we get to the guts of privileges, as this is not trivial (but nevertheless straight-forward I hope). The general idea is based on the scope of object a privilege applies:

System default privileges obviously have the largest scope, they apply to everyone. The next smaller scope are privileges which are assigned to groups in general, followed by privileges assigned directly to a user.

From this point on, the privileges of the content objects are next in line, starting at the top-level objects again (for example a root topic). The smallest scope finally then has the object that is being accessed itself.

Let us visualize this a bit:

^ larger scope     System default privileges
| Privileges for USERS/ANONYMOUS
| Root Midgard group
| ... more parent Midgard groups ...
| Direct Midgard group membership
| Virtual group memberships
| User
| CLASS style per-class global privileges
| Root content object
| ... more parent objects ...
v smaller scope Accessed content object

Implementation notes: Internally, MidCOM separates the "user privilege set" which is everything down to the line User above, and the content object privileges, which constitutes of the rest. This separation has been done for performance reasons, as the user's privileges are loade immediately upon authentication of the user, and the privileges of the actual content objects are merged into this set then. Normally, this should be of no importance for ACL users, but it explains the more complex graph in the original mRFC.

Predefined Privileges

The MidCOM core defines a set of core privileges, which fall in two categories:

Midgard Privileges

These privileges are part of the MidCOM Database Abstraction layer (MidCOM DBA) and have been originally proposed by me in a mail to the Midgard developers list. They will move into the core level eventually, but for the time being MidCOM will control them. Unless otherwise noted, all privileges are denied by default.

MidCOM privileges

Stuff like midcom:approve will go here once they are defined.

TODO / Ideas