- 1 Business Requirements
- 1.1 What resources do we want to control access to?
- 1.2 Who needs access to these resources?
- 1.3 What are some restrictions in our access model?
- 2 Technical Implementation
- 2.1 Role Based Access Control (RBAC)
- 2.2 PKP's RBAC implementation
- 2.3 Policy Configuration and Enforcement
- 2.4 Database Model
- 2.5 Class Model
- 2.6 Open Questions
What resources do we want to control access to?
- Access to Features: These are logically grouped into "visual blocks" which form "pages" which are attributed to "workflow stages".
- Access to Application Objects
A workflow stage is defined as a number of editorial actions applied to one and the same "bundle of objects", all assigned to the same submission. This can be files, documents, reviews, etc. Files and other objects can be copied or promoted from one workflow stage to the next. Files and other objects can also be added to or removed from a given workflow stage.
A certain action (e.g. a review) can be applied to a sub-set of these objects (e.g. files selected for review) but objects that are not attributed to the given workflow stage are not accessible to any action within the workflow step.
All objects attributed to a submission must at the same time be attributed to a workflow stage.
Workflow stages in OMP are:
Workflow stages in OJS are:
Workflow stages in OCS are:
Workflow stages in the Harvester are:
Pages present a number of logically grouped features to the end user. A new page is displayed when entering a URL or clicking a link (or more technically: making a full HTTP request). There might be several URLs pointing to different versions of the same basic page.
The smallest entity that we allow access to is a visual block on a page. This can be a grid with grid actions, it can be logically grouped read-only information or any other "bundle" of elements grouped together on a page and managed as a "whole" when it comes to access control. Visual blocks often display objects retrieved from the database like submissions, files, reviews, notes, etc. Each visual block defines the way these objects will be selected and filtered based on the user's permission that is currently looking at these data.
Visual blocks can be implemented as (AJAX) components which allows them to be updated, added to or deleted from the page without a full page reload.
A visual block usually presents or acts upon one or more application objects. A grid can contain several files or meta-data can be grouped and we can allow access only to certain groups of meta-data properties to a given user while other meta-data remains hidden.
Typical application objects that we want to allow access to are submissions, files, reviews, documents, etc.
You can roughly think of application objects as anything that can be added, deleted and edited in the database.
A less precise concept but one that is rather useful to distinguish between different features and categorize them is "access mode". Typical access modes are create, read, update and delete. Access modes are somehow the link between "features" and "application objects". Usually a given feature provides access to one or more application objects in a certain access mode.
A grid may for example have buttons to add, delete and edit objects that correspond to the add, delete and edit "features" of a grid.
To sum up we can say that the basic resource that we grant access to is: a visual block that allows inspection or manipulation of one or more application objects in a given access mode.
Who needs access to these resources?
PKP applications grant access to application users which represent (=identify) human actors accessing the application.
It is of course inefficient to define individual access levels for every user. We therefore have to find intelligent ways in which we can group users so that they can be granted access in a more efficient way.
We have to make sure that we make the groups small enough to be able to define the level of differentiated access that we need to implement our specifications. At the same time, however, we want the groups to be as large (and as few) as possible to keep the administrative burden down.
The basic unit that can be used to group users with the same access levels is called a "user role" in PKP applications. A user role needs to unequivocally define all features and application objects available to its members. What we said in the previous paragraph means that we need to create roles in a way that within one role all users have the same homogeneous permissions but that no two roles are equal.
We therefore need a different role for all types of "bundles" of features and object access that are required in the application.
What helps us in this respect is that in our business (the publishing business) we can create all roles from a combination of a few feature sets and basic object access logics.
We identify and define these fixed feature sets and object access logics in the next two paragraphs so that we can base our role definitions on them.
Feature Access Definition
We can group features that can be accessed by a given role into feature sets. Typical feature sets that we can address as a single unit are:
- all features within the application
- all features within a worflow stage
- all features on a given page (e.g. review page for reviewers)
- one or more visual blocks on a page.
The most frequent feature set to be adressed in OJS, Harvester and OCS is the page level with a few block-centered exceptions. In OMP the block level will be more important in many situations.
Feature sets also define for every block, page or workflow stage in which access mode it can be accessed. This may be addition, reading, updating and deletion of objects.
A typical feature set definition would therefore be: Members of the author role have read access on all features of the submission stage page with exception of file access where they can also add (=upload), delete and edit (=file metadata) objects.
Object Access Logic
While feature sets are fixed and can be "hard-coded" into the roles, we need to give our users quite some flexibility when it comes to defining object access. Not all publishers define object access in the same way and object access definitions need to be very granular sometimes.
A few examples:
- All reviewers basically need the same functionality to review a monograph or an article but of course not all reviewers need access to the same articles. They have access only to a small selection of articles, a single monograph or a single conference paper.
- Series editors (OMP) and section editors (OJS) have access to a sub-set of articles/monographs within a journal/press. The functionality, they have access to, is largely the same as that of a journal editor or press editor, though.
In some instances we have to define access on a per-object level. While we can say that authors see all submissions contributed by them we might have a situation in which a specific copyeditor has access to a completely arbitrary set of submissions which cannot be grouped by any pre-defined criteria.
Although we obviously cannot "hard code" object access permissions themselves into our roles, we still can identify a few basic types of access logic that we can then attribute to roles and leave the actual permission administration to the end user.
All such access logics are:
- access to all objects of a kind throughout the application, e.g. site administrators
- access to all objects of a kind within one context (press, journal, conference, etc.), e.g. press editors or journal managers
- access to all objects of a kind within a subset of a context (series, section, etc.), e.g. series editors or section editors
- access to objects by ownership, e.g. authors' or reviewers' access to submissions/reviews they uploaded themselves
- access to objects via individual rights assignment based on pre-defined or custom user groups
While the first four access logics are obvious, the last one needs a bit more explanation. It actually means that we allow access to arbitrary application objects based on user group assignments. To explain this we first need to introduce the user group concept.
PKP applications allow organizations to create and maintain groups that, from a technical viewpoint, provide the exact same level of access to the application. If you followed the argument so far then you'll say that this is not efficient as it means maintaining duplicate groups which increases application administration cost. While this is true from a technical standpoint, there are reasons why organizations may want to keep groups apart even if they have the same access level.
In the case of OMP for example, authors and volume editors have the same access rights. Still it makes sense to name them differently as they are semantically different from a publisher's point of view.
PKP applications contain a number of pre-defined user groups but organizations can freely add, rename or delete user groups per context (press, journal, etc.). A user group always has one of the application role assigned which unequivocally defines the feature set and object access logic for that group.
Individual Rights Assignment
Based on user groups it is now possible to define highly flexible object access.
A user can be granted access to an object within one of the user groups she has been assigned to. This gives the user access to all the features defined for the role attached to the user group with respect to the assigned object.
- A press editor (which is a pre-defined user group which has the managerial access role assigned) creates a new user group called "translators" and assigns it to the editorial role.
- Then the press editor can assign users to that new user group which act as translators.
- Finally the press editor will now be able to assign a user as a translator to an arbitrary submission at a certain workflow stage, say the copyediting stage.
This will give this single user access to the features defined for the editorial role within the copyediting workflow stage but only for the selected submission. It won't give the user access to editorial features in other workflow steps, it won't give other users of the same group any additional access rights and it won't give the user any rights to any other submission.
What are some restrictions in our access model?
Restrictions on Roles
Different user groups that are based on the same basic role cannot be granted different types of access. This includes access to either features or objects.
Example 1 - Different Feature Sets: If the reviewer group and the copyeditor group belonged to the same basic role (e.g. "editorial role") then our current approach makes it impossible to give copyeditors access to different pages within the review process than we allow reviewers to look at. The implication is that if reviewers need their own set of pages, then they must belong to their own basic role.
Example 2 - Different Object Access Logic: We also cannot manage object access based on a different logic for two different user groups that are based on the same role. If series editors see their objects (submissions) based on series and press editors see their objects based on the press they belong to, then these two user groups cannot be based on the same role model. The implication is that series editors and press editors need to be based on two distinct roles.
Conclusion: Reviewers, series editors and press editors all have to be based on different basic application roles!
Watch out! These are examples identified so far, but there are probably others.
Restrictions on Feature Definitions
The smallest unit to define feature sets is a "visual block". Unique and definite access rights (access mode, feature set and object access logic) for a given role must be defined for every "visual block".
Restrictions on Object Access Definition
Individual object access can be attributed on a workflow stage level only. This means that workflow stages are the smallest unit to differentiate between individual user's access levels. Finer granularity can only be achieved by defining additional basic roles.
Role Based Access Control (RBAC)
The PKP framework implements role-based access control (RBAC). The elements of a typical RBAC system are:
- Subjects (Agents, Users)
- Objects (Resources) to which access should be controlled
- Access Modes (e.g. "read", "write", "execute", etc.) - sometimes also called "operations" or "actions"
- Permissions that define a certain mode of access to a resource
Subjects and permissions are assigned to roles. Roles are thereby an efficient way to define which subject has access to which resource and through which access mode.
Refinements of this basic access control model are possible:
- Roles can be organized in a hierarchy whereby a subordinate role "inherits" permission assignments of its parent role.
- Subjects, objects, access modes and permissions can be organized in groups so that they can be assigned or otherwise handled in "bulk". Groups of permissions are calles "policies".
PKP's RBAC implementation
PKP does not require all elements of the generic RBAC model. We apply the model to our application in the following way:
- The subjects in PKP applications are called "users"
- The resources we control are handler operations and database objects (e.g. articles, files, papers, etc.).
- PKP applications currently use a hard coded, non-configurable role model (e.g. in OJS: "editor", "section editor", "author", "reviewer", "journal manager", "site administrator", etc.).
- PKP applications do not currently implement an explicit role hierarchy although in practice there are implicit role hierarchies:
- In OJS, the hierarchy goes from the site administrator over journal managers and editors down to section editors and subscription managers inherit a few permissions from the journal manager.
- Some roles (e.g. 'site administrator' and 'journal manager' in OJS) can "log in as" any other user, thereby temporarily inheriting all permissions of the impersonated user's role.
- Permission-role assignments are hard-coded into the application. Handler operations define which roles may access it. Currently authorization checks are part of the request "validation" procedure.
- Most of the time all operations within a handler may be accessed by the same roles. In these cases the handler constructor (for pages) or handler-wide validation method (for AJAX controllers) implement the permission-role assignments for all contained operations. In other words: We usually define a policy that contains permissions for all operations of a handler.
- HandlerValidatorRoles classes define the assignment of operations to roles
- Database object permissions are usually either hard coded into the validate() method or the handler operation itself
- There are a number of other permission-related checks (e.g. check for a given context, check for HTTPS protocol, etc.) which are also coded into the validate() method or the handler operation
- Usually operations only define one mode of access ("execute"). There are a few exception to this rule, where different roles may access the same operation in different ways, e.g. the differentiated access of "editors" and "section editors" to some of the operations in the editorial process in OJS. In these cases access modes are hard coded into the operation.
- Subject-role assignments are configurable via the role administration UI in PKP applications.
- We recently introduced configurable subject groups or in PKP terminology "user groups" that allow bulk assignment of several users to one (and only one) of PKP's hard coded roles. The names of user groups can be freely defined in the role administration UI. Applications that make use of user groups will no longer allow direct subject-role assignments. It must be stressed that user groups are not roles although end users do not necessarily need to understand this distinction. PKP developers should be very clear in their terminology, though, to avoid confusion and implementation errors. The term "flexible role" is deprecated in favor of "user group" and should no longer be used.
Policy Configuration and Enforcement
The following functions must be implemented within any authorization framework to configure and actually enforce policy:
- a tool to administer policies
- a component determining authorization decisions based on policy
- actual authorization decision enforcement
- a policy information source (e.g. a database)
As we hard code most of our permissions (namely assignement of roles to handler operations) we do not need to administer this kind of permission. We do however have to administer the assignment of subjects (users) to user groups, the assignment of user groups to roles and the assignment of users to certain types of data objects (e.g. sections or articles in OJS or series in OMP).
User-user group assignment is done on the user enrollment pages which shows all user groups and allows users with the appropriate access level to add/remove users to/from user groups.
User group-role assignment is only relevant to OMP as OJS/OCS do not implement the user group abstraction but directly assign users to roles. In OMP there will be a grid which is part of the press settings that allows members of managerial roles to add new user groups with a given role assigned or remove user groups from a role. NB: The same grid is used to assign workflow steps to user groups. This is, however, not a permission assignment! It simply determines which workflow stages will be linked by default to the user. The user always has the right to access all workflow stages and features assigned by permission policy to the assigned role. The role is the only instance that has permissions attached to.
Assignment of users to data objects like series/monographs (OMP), sections/articles (OJS), tracks/papers (OCS), etc. is done at several places in the application. In the case of articles, papers, monographs, etc. we implement an "owner" concept. This means that the author of an article is automatically being assigned to it as its creator. Series, sections and tracks have to be assigned explicitly to a user.
Policy Information Sources
Policy information comes from several sources:
- The user-user group assignments as well as the user group-role assignments are held in database tables and will be queried there.
- Permissions defined via descendants of the HandlerValidator class are usually either defined in the handler's constructor or in its validate method. There are rare cases where the handler operation itself adds additional policy checks. This includes role-handler operation assignments as well as a few more complex decisions like HTTPS protocol enforcement.
- Permissions regulating access to data objects are usually defined directly in the handler operation code. In this case policy definition and enforcement are held in the same place. Such inline data access policy definitions can be quite complex, e.g. in the case of subscription based access. They nearly always require inspection of the data objects or database access as well as inspection of the application environment (context, settings, etc.).
We currently take authorization decisions at different places within the application:
- All decendents of the HandlerValidator class explicitly take authorization decisions via their isValid() method. The decision request is made by the validate() method implemented in the base class of all handlers, PKPHandler.
- Data object based decidions are taken directly within the handler that makes the decision request: either as part of the validate() method call or within the handler operation itself.
Authorization Decision Requests and Enforcement
Currently all authorization decision requests emanate directly from the handler and will also be enforced there:
- Authorization decisions taken by way of the HandlerValidator classes will be either enforced in the PKPHandler (e.g. by re-directing the request to the log-in or another permitted page) or in the handler operation itself by letting the validate() pass the decision result to the handler operation which then is responsible to correctly enforce it.
- Authorization decisions regarding data objects or decisions which are not taken via HandlerValidator classes are enforced where they are taken: in the handler operation or in the validate() method.
Evaluation of the current Authorization Framework
It becomes obvious from the above analysis that our current authorization framework is limited in several respects. This is not necessarily a bad thing as long as the framework corresponds to current requirements and is flexible enough to be extended within a reasonable range in the future:
- Hard coded permissions: permissions cannot be configured by the end user nor can we create "permission profiles" for different applications or use cases if such would become a requirement. This also implies that if we need to implement different permissions for different applications then we have to write application-specific sub-classes which means that permission definitions either have to follow the inheritance hierarchy or have to be duplicated in several places. Hard coding permissions also means that requirements like subscription based access have to be hard coded into the operations rather than providing central access profiles which could be changed in one single place.
- Hard coded roles: If we want to introduce a new role we'll have to introduce it in code which means that we cannot let the user introduce new roles with differentiated access levels.
- Scattered authorization functions: We currently have several different models for the distribution of authorization functions accross the
Entities and Relationships
- RBAC subjects, objects, object groups, roles, permissions and permission assignments are all hard coded into PKP applications and are therefore not mapped to any database entities!
- The interface of hard coded roles and the database is via PHP role constants (e.g. ROLE_ID_EDITOR).
- The "roles" table that has been present in earlier releases of PKP applications is not representing roles but user-role assignments. The name of this database entity is conceptually wrong and was replaced with the introduction of configurable user groups.
- Only configurable entities and relations are represented as entities in the database. These are "users", "user groups", "user - user group assignments" and "user group - role assignments". The corresponding database entities are "users", "users_user_groups" and "user_groups".
- As with all PKP entities, the user and user group entity tables will be accompanied by a corresponding settings table that allows for flexible meta-data (=attribute) assignment and internationalization.
- The "user_groups" table contains a foreign key to the non-database "role" entity. This means that the role column in "user_groups" contains references to the above mentioned role constants defined in the application code.
- one user can be assigned to several user groups, one user group can contain several users (0..n:0..m relation)
- one user group can be assigned to exactly one role, one role can have several user groups assigned (1..1:1..n relation)
- every role has a standard user group assigned which will never be deleted (which explains the 1.. relation).
The following classes are designed with approximate structural XACML compliance in mind.
We implement the following policy types (base class AuthorizationPolicy):
- HandlerOperationPolicy (defines access to a group of or all operations within a handler)
- subject: user, role (including pseudo roles like ROLE_PUBLIC_USER, ROLE_AUTHENTICATED_USER, ROLE_SUBSCRIBED_USER), in the case of subscription: domain
- object: handler operation
- action: execute (except for site-wide roles)
- environment: settings (e.g. installation state, restricted site access, publishing mode, request encryption state), context (any context or a specific one)
- DataObjectPolicy: A policy that controls access to database objects.
- subject: user, role
- object: entity name, id
- action: create, update, delete, view, list, ...
- environment: handler, operation, settings, e.g. "enable comments", "subscription required", etc.
We implement the following data access policies (base class DataObjectPolicy):
- object assignment policies: SeriesEditorPolicy, SectionEditorPolicy, ContextLevelWorkflowStagePolicy, SubmissionLevelWorkflowStagePolicy, etc.
- object ownership policies: ArticleOwnershipPolicy, SubmissionCommentOwnershipPolicy, AnnouncementOwnershipPolicy, etc.
- combinations of both, e.g. pre-publication article access is defined as either owner or editorial role
We define the following pseudo roles:
- ROLE_ID_PUBLIC_USER: any user with a session
- ROLE_ID_AUTHENTICATED_USER: any authenticated user (includes account expiry and password change requirement check)
- ROLE_ID_SUBSCRIBED_USER: an authenticated user subscribed to the given data object
We define the following policy combination rules:
- Deny overrides
- Permit overrides
- Can the "groups" table be integrated with the "user_groups" table. This would be preferable
- Can we better implement role inheritance so that the currently implicit hierarchy is made explicit and enforced systematically?