Permissions
Warning, this page will be heavy on mathematics.
Define a User to be a (mostly human) member that can login on his User account. An Entity can be any object in the system, the most common will likely be Bodies, Circles and Users, but it is entirely possible for an Address, of even something such as a GlobalOption to be considered an Entity in this explanation.
First off, intepret the problem of dealing with permissions as a graph-based problem, a permission entity A has over entity B is then defined as a (uni-directional) edge from node A to B. The desired permissional model will then be the combined graph of these nodes and edges.
Every entity has 2 ways it can grant permissions:
- It can define permissions it has on itself
- It can define permissions it has over others
A permission can be granted by achieven either of those. Let's consider one of both cases:
- Entity A wants to do an action on Entity A, for example changing it's name. Entity A then checks if it can give itself this permission, which will likely be granted, and therefore this action will succeed.
- Note that while this might sound unecessary now, this will become useful later on.
- Entity A wants to do an action on Entity B, for example changing entity B's name. Let's say Entity A has this permission over others, and Entity B is considered to be in this 'others', therefore the action will succeed
- Defining this 'others': While the permission entity A has over others are defined in entity A, the definition of this 'others' is not, this is crucial to understand and probably feels counter-intuitive. Entity A does not define this others, but other entity define themself to be in Entity A's 'others'. This works as follows, using the example above: Entity A tries to do an action on Entity B (renaming), entity B says it requires permissions for this, and will thus start a search for this specific permission. Since it is Entity A trying to do the action, Entity B skips asking itself, but instead starts asking the Entity's it trusts (Entity B's delegates), Entity A happens to be one of these delegates, placing Entity B among entity A's others. Since entity A has defined the renaming permission over others and Entity B has been shown to be in this 'others', the permission is granted.
- It can help to say Entity B trusts entity A to make correct decisions on it's permissions.
- Defining this 'others': While the permission entity A has over others are defined in entity A, the definition of this 'others' is not, this is crucial to understand and probably feels counter-intuitive. Entity A does not define this others, but other entity define themself to be in Entity A's 'others'. This works as follows, using the example above: Entity A tries to do an action on Entity B (renaming), entity B says it requires permissions for this, and will thus start a search for this specific permission. Since it is Entity A trying to do the action, Entity B skips asking itself, but instead starts asking the Entity's it trusts (Entity B's delegates), Entity A happens to be one of these delegates, placing Entity B among entity A's others. Since entity A has defined the renaming permission over others and Entity B has been shown to be in this 'others', the permission is granted.
Optimizations:
- Remove the need for Users to be considered as an Entity (removes ~10.000 entities)
While some actions might be initiated by an Entity itself, we are mostly interested by the permissions User A has over entity X. Note that User A could be considered an
A proposal on implementing permissions.
- Split between actions on lists and single objects.
- Only Users have rights.
- Bodies define default rights between its Users and default rights the User have on the Body
- Body Circles grant extra rights between Users in the same Body Circles, extra rights over Users within that same Body, as well as defining extra rights Users of that Circle have over the Body
- Global Circles grant extra rights between Users in the same Global Circle, extra rights over Users in general, as well as defining extra rights over other (Global and/or Body) Circles
Group - A parent of a set of Users. For example: Body, Circle, Event.
METHOD 1: Gather permissions first
User - Body
- Start with the default rights the User has over that Body
- Find User relations to Body
- Find all the Body Circles the User is in
- Filter on the Body in question
- Find permissions for each relation (role)
- Merge permissions
- Apply permissions
User - Bodies
- Find User relations to global Circles
- Find User circles
- Check each Circle for global parent Circle
- Get Both
- Find permissions for each relation (role)
- Merge permissions
- Apply permissions
User - Circle
- Get default rights the Users of the Circle have over the Circle
- Find User's global Circles
- Find User's Body Circles
- Find parent Global Circles of those Body Circles
- Find permissions each of the Global Circles have over Circles
- Merge permissions
- Apply permissions
User - User
- For each User:
- Find the Bodies the User is in
- Find the (Body) Circles the User is in
- Find the Global Circles the User is in through the Body Circles
- Query other microservices for relations.
- Get the cross-section of the groups
- Find permissions for the remaining common relations
- Merge permissions
- Apply permissions
User - Users
- Specify the group of which to use the rights (a single group)
- Find Users within that Group
- Find permissions over those Users based on the given Group
- Apply permissions on each User
A cross section with the groups of a User with every set of groups from Users in the system would result in a too complex query, therefor this is only allowed for single User on single User.
User - External Object
- Delegated to the external object
To Be Solved:
Allowing external objects to have circles assigned to them. → Giving Circles a variable parent Object
METHOD 2: Search required permissions - abstract
Have 2 Permission interfaces/traits/basemodels/whatever and initiate a (preferably breadth-first) search to find a GPO that can grant the User this permission.
- RequiresPermission Object (RPO)
- Pretty much everything, including Bodies and Circles
- GrantsPermission Object (GPO)
- Typically Bodies, Circles
- Extension of an RPO
- When a User wants to do an action on a RPO, the required permission will be determined first
- If default permissions allow the action, permission is granted
- Next the RPO asks its GPO's whether any of them can grant the User permission for this action on itself
- The GPO then takes the following steps upon receiving a request from the RPO:
- The GPO can grant this permission itself
- Typically this comes down to whether both the User and the requesting RPO are members of this GPO (and members receive those rights on eachother)
- Next, the GPO delegates this RPO's permission request from the User (acting as an RPO)
- The GPO gathers the set of GPO's it trusts
- Typically Circles inside a Body or Bodies/Circles it extends
- It queries these GPO's for the permission requests (and step 4 restarts)
- The GPO gathers the set of GPO's it trusts
- The GPO can grant this permission itself
- At any time once a permission is found, the action is approved
- If the search ends without result, permission is not granted
- Loop prevention has to be done
- Several optimization tactics can probably implemented
- Short-routing frequent actions, basically knowing where to search for a permission
- Filtering trusted GPO's on Circles the User is a member of
- This is very much a networking question
- Existing network optimization (caching) techniques might be usable