Chapter 27. Setting Permissions

Within DOC, any operation on application elements requires specific permissions. For more details, refer to Section Understanding Operations.

Permissions can be defined depending on the origin of the action. For more details, refer to Section Defining Permissions.

Administrators can implement various permission configurations depending on the case at hand. For more details, refer to Section Implementing Permission Samples.

[Note]

Note that:

1. Understanding Operations

Operations depend on:

  • The user and its role(s);

  • The scope, i.e. if it is part of a job, and if so, which job;

  • The type of operation, such as access, modification, creation, etc.;

  • The application element on which the action is performed, as well as its owner, container, and permission group(s); and

  • The permission rules that have been defined in the application.

From all but the last of these factors, the permission system determines a list of accesses that are required for the user on the target application element. For example, to rename a dashboard, a user must have ACCESS, MODIFY rights on said dashboard. For more details on the required accesses for operations on each type of application elements, refer to Section Understanding Access Rights.

If the element is a scenario, the operation may involve a scenario lock. For more details, refer to Section Understanding Scenario Locks.

Specific rights must be granted to the administrator(s) in charge of managing the permissions, which are themselves considered as a type of application element. For more details, refer to Section Understanding Operations on Permissions.

1.1. Understanding Access Rights

Users require specific access rights to perform operations, for example, "User Alice needs MODIFY access right on scenario S1 to modify the content of a row". For more details, refer to Chapter Managing the Application Data.

At least one access right requirement is emitted by basically any operation. It is composed of:

  • a user,

  • an access right,

  • and an application element.

An access right requirement is decided by evaluating it against the permission rules. This is a three-step process:

  1. Applicable rules are looked up;

  2. The most specific ones are retained;

  3. The decision is computed.

Access rights can be of the following types: ACCESS, MODIFY, DELETE, CREATE, or PERMISSIONS.

Operations can be performed on the following application elements:

  • Workspaces, scenarios and scenario links. Note that:

    • This includes the creation, access and deletion as well as the edition of their properties and content.

    • A scenario contains an instance of the data model defined before generating the application. For more details, refer to Chapter Defining the Data Model.

    • A workspace contains a number of scenarios. A scenario is always contained in a workspace.

    • Scenarios and workspaces have an owner, who initially is the user that created them.

    • A scenario can be locked.

    • If the application uses a composite data model:

      • In order to have ACCESS permission on a scenario, the user must have ACCESS permission on all visible scenarios.

      • To edit an entity attribute (in scenario S1 for example) that is retrieved from a referenced scenario (S2), the user must have MODIFY permission on said referenced scenario (S2).

      • Creating a scenario link to a scenario adds said scenario to a workspace accessible to users that cannot access the current Workspace.

      • Editing a scenario in a workspace also impacts its corresponding scenario links, even when they are in other workspaces.

      • Deleting a scenario link does not delete the linked scenario. However, deleting a scenario does delete all related links.

  • Views, dashboards and application preferences. Note that:

    • This includes the creation of a view or dashboard, access to the view or dashboard, modification of a property of the view or dashboard (e.g. its name) or of its content (the widgets it contains), deletion of the view or dashboard.

    • Although views and dashboard are different from a user experience viewpoint, they are gathered as a single application element type.

    • A view or dashboard is not contained in another application element. It has an owner, who initially is the user that created it.

  • Tasks and jobs. Note that:

    • There is no operation on a task except including it in the list of tasks, as they are created statically by code. On the other hand, jobs can be created, their properties (step list, outputs, log) can be displayed, a job can be stopped, and it can be erased from the list of jobs.

    • As a job is the execution of a task, jobs that execute a given task are considered to be contained by the task, in the same ways as a workspace contains scenarios. From the viewpoint of the permission system, launching a task execution is thus like creating a job contained in the task.

    • Jobs have an owner, who is the user that launched their execution. Tasks have no owner.

  • Permissions. Note that:

    • Like scenarios, workspaces, tasks, jobs, views and dashboards, permission rules can also be configured through application preferences and permissions management to set who is allowed to access and modify them. For more details, refer to Section Setting Application Preferences.

    • Permission rules cannot be deleted nor created (one global instance of each rule preexists). They have no owner. For more details, refer to Section Understanding Permission Rules and Rulesets.

The permission system evaluates each access required by the operation and the operation is allowed or forbidden. The table below lists the classical Create, Read, Update and Delete operations on each of the application element types, and indicates which accesses they require.

Figure 27.1. Understanding CRUD Operations on Common Element Types
Understanding CRUD Operations on Common Element Types

1.2. Understanding Permission Rules and Rulesets

As described in Section Defining Permission Rules and Rulesets, permission rules are gathered in rulesets.

A ruleset is attached either to:

  • An application element,

  • A permission group, or to

  • The application itself.

The matching part of a permission rule is made of a user pattern, an access right, and an application element type. When performing an operation on a given application element, the following rulesets are searched in this order until at least one positive match is found:

  1. the ruleset attached to the application element;

  2. the ruleset attached to the element that contains the application element, if any;

  3. the rulesets attached to the permission groups that contain the application element;

  4. the rulesets attached to the permission groups that contain the element that contains the application element, if any;

  5. the ruleset attached to the application.

    [Note]

    Note that, for creation requirement, the application element considered is the candidate container, if any. If it is null, only the ruleset attached to the application is searched.

In the example of the requirement "User Alice needs MODIFY access right on scenario S1" where:

  • S1 belongs to permission groups G1 and G2,

  • S1 is contained in workspace W1, which belongs to permission groups G3 and G4,

The following rulesets would be searched:

  1. First, the one attached to S1;

  2. Then the one attached to W1;

  3. Then the ones attached to G1 and G2;

  4. Then the ones attached to G3 and G4;

  5. And finally, the one attached to the application.

When the search is conducted on the rulesets attached to the permission groups that contain a given element (steps 3 and 4 above), all the rulesets that contain the elements are searched before deciding to stop or proceed.

As a result, the collected rules may come from several rulesets at these steps. If one of the lookup steps above yields a collection of two permission rules or more, only the most specific ones are retained. The specificity of a permission rule is determined by that of its user pattern. That is, in decreasing order of specificity: USER(u), OWNER, ROLE(r), EVERYBODY. This specificity filter is useful when a ruleset defines a permission rule for the general case using EVERYBODY, and another rule for a more specific case, for example, using ROLE(r).

If both rules are applicable, this selection step retains only the one for the role. Note that even after this selection, several rules with the same specificity may be applicable. This may, for example, occur when the user in the access requirement holds several roles. This is not a problem, and is addressed in the next step.

If one rule or more were found and selected, the operation is allowed if all the decision parts of these rules are true, and forbidden if the decision part of at least one rule is false.

If no applicable rule was found, the operation is allowed.

1.3. Understanding Scenario Locks

Different locks can be set on a scenario. For more details, refer to Sections Understanding the Scenario Service Document Properties and Using the Scenario List Widget.

A user lock can be either a persistent lock or a session lock. The only difference is that a persistent lock remains present on the scenario until explicitly removed, while the session lock is automatically removed at the end of the user session, that is, when the user logs out of all his/her sessions, or when these sessions expire.

  • The user lock can be set by a user.

  • Once the lock is set, only the user who locked the scenario can modify the locked scenario.

  • When a scenario is locked with a persistent user lock, setting a session user lock replaces the persistent lock with a session lock, and vice versa.

  • Both persistent and session locks can be removed manually at any time.

A system lock is set by a job, that is, the execution of a task. Once the lock is set by a job, modifying operations on the scenario can only be performed in the scope of this job. For more details, refer to Chapter Understanding the Execution Service.

  • The system lock is automatically removed when the job terminates. Should a crash prevent the lock from being removed, the user who launched the job and users with the PERMISSIONS_ADMIN role can remove it from the web client.

  • When a system lock is added or removed on a given scenario, a read-only lock is also added or removed on any visible scenario of this scenario. By doing so, the system ensures that the visible scenarios will not be modified during the execution of the job. However, since the data of these scenarios will not be modified by this job, the read-only locks do not prevent from running some jobs on the referencing scenarios of the scenarios locked with read-only locks.

  • The read-only lock is a type of system lock set by any job running on a referencing scenario. Once a read-only lock is set, any modification of the scenario will be refused. On the other hand, the scenario can still be visualized in dashboards and jobs can be launched on any referencing scenarios. The read-only locks are automatically removed when the job terminates. Like a normal system lock, should a crash prevent the read-only lock from being removed, the user who launched the job and users with the PERMISSIONS_ADMIN role can remove it from the web client.

A lock access requirement is emitted by a MODIFY operation on a scenario. This operation, performed by a given user, may be performed in the scope of a job, or not. For instance, a system lock can be put on a scenario by DOC when using it in a job. The lock is owned by the job. In contrast, a user lock is put by a user, typically using the web client; In this case, the lock is owned by the user.

Such a requirement is decided using the following rules:

  • If the scenario holds a read-only lock, then the operation is refused.

  • If the scenario holds a user lock, then the lock must be owned by the user who performs the operation.

  • If the scenario holds a system lock, then the operation must be performed in the scope of the job that owns the lock.

As a few exceptions, lock access is additionally granted on some lock and unlock operations, so that:

  • A user may put or remove a user lock from the web client on a scenario on which s/he is currently executing a job.

  • A user may remove a system lock from the web client from a scenario on which s/he is currently executing a job.

  • A user with the PERMISSIONS_ADMIN role may remove any user, read-only or system lock.

1.4. Understanding Operations on Permissions

The table below list the operations that relate to permissions, namely:

  • Querying or changing the owner of an application element;

  • Querying the list of permission groups and the application elements that they contain;

  • Creating or deleting a permission group;

  • Adding/removing an application element to/from a permission group; or

  • Querying or changing the permission rules in a ruleset.

The control over these operations is implemented with the access requirements and permission rules introduced above. Depending on the operations, these access requirements and permission rules may involve:

  • ACCESS and MODIFY access rights on the APPLICATION_PERMISSIONS element; and

  • PERMISSIONS access rights on target application elements.

Figure 27.2. Understanding Operations on Permissions
Understanding Operations on Permissions

The logic in the table above is:

  • To query components of the permission system that are not tied to application elements, you must have ACCESS on APPLICATION_PERMISSIONS. This involves: the ruleset attached to the application, the permission groups (which groups exist, not which elements they contain), the rulesets attached to permission groups.

  • To modify components of the permission system that are not tied to application elements (same as above), you must have ACCESS and MODIFY on APPLICATION_PERMISSIONS. Again, this does not involve which application elements the permission groups contain.

  • To query components of the permission system that are tied to application elements, you must have one of the following permissions which are considered to provide you sufficient access: PERMISSIONS on the application element, or ACCESS to the application element, or ACCESS to APPLICATION_PERMISSIONS. This involves: the ruleset attached to the application element, the permission groups to which the application element belongs, the owner of the application element when applicable. This also means that to prevent you from seeing this information, one must explicitly forbid the three accesses listed above.

  • To modify components of the permission system that are tied to application elements (same as above), you must have PERMISSIONS on the application element. Note that neither ACCESS nor MODIFY to the application element, nor ACCESS or MODIFY to APPLICATION_PERMISSIONS are required. This allows to control who can set permissions on an application element independently from who can see or update it.

[Note]

Note that, whether a given user has the required access rights on the respective application elements or not, is determined by the permission rules. In addition, a user that carries role PERMISSIONS_ADMIN is automatically granted ACCESS and MODIFY on APPLICATION_PERMISSIONS, as well as PERMISSIONS on all application elements. This is intended to avoid deadlocks, where a user with high privileges would accidentally (or not) remove the permissions to edit permissions to one or several elements of the application to all users, her/himself included.

2. Defining Permissions

Permission rules, rulesets and groups are defined in the application configuration file app-config.json. You can export and import them from and into the application, either using the web client or as part of the application backup and restore. For more details, refer to Chapter Configuring the Application and Section Backing Up and Restoring the Application.

2.1. Defining Permission Rules and Rulesets

Permission rules are the means by which administrators define which operations on which application elements are allowed or forbidden to which users. For more details, refer to Section Understanding Operations.

An application that has just been generated contains:

When defining permission rules, the life cycle of an application comes into play. For example, in order to prevent users to create workspaces, some workspace(s) must be created upfront and specific permissions must be defined. If no permission rules are defined in an application, all users are allowed to perform any operation.

Permission rules are gathered into rulesets. Rulesets are associated with, either:

  • The application itself;

  • Application elements; or

  • Permission groups.

The ruleset of an application element (or of a permission group, etc.) is thus the collection of the permission rules attached to the element (or the group, etc.).

A permission rule has a matching part and a decision part.

The matching part is composed of:

  • A user pattern, which is one of the following (in decreasing order of specificity):

    • USER(u) means that the rule will only apply to the user u;

    • OWNER means that the rule will only apply to the user who owns the application element to which the operation is applied;

    • ROLE(r) means that the rule will only apply to users who have the role r;

    • EVERYBODY means that the rule will apply to all users.

  • An access right that is either ACCESS, MODIFY, DELETE, CREATE, or PERMISSIONS.

  • An application element type that is either WORKSPACE, SCENARIO, TASK, JOB, VIEW_DASHBOARD, APPLICATION_PREFERENCES, or APPLICATION_PERMISSIONS.

  • The decision part, which is a Boolean value.

The following permission rules are defined in the ruleset attached to a freshly generated application:

// Workspaces: Everybody can create a workspace, and then only the owner of a workspace can access it.
EVERYBODY, CREATE, WORKSPACE, true
EVERYBODY, ACCESS, WORKSPACE, false
OWNER,     ACCESS, WORKSPACE, true

// Scenarios: Only the owner of a scenario can delete it. (Duplicate these lines with MODIFY if you want
// to make scenarios read-only except for their owners.)
EVERYBODY, DELETE, SCENARIO, false
OWNER,     DELETE, SCENARIO, true

// We want users to have only access to scenarios that are contained in workspaces that they have access to.
// To this end, all rules on workspace access have to be duplicated on scenario access, here and on
// individual workspaces (see initWorkspaces).
EVERYBODY, ACCESS, SCENARIO, false
OWNER,     ACCESS, SCENARIO, true

// Views and dashboards: Everybody can create and access views and dashboards; only owners can modify or
// delete them. In addition, user 'gene_admin' has full permission on views and dashboards.
EVERYBODY,        MODIFY, VIEW_DASHBOARD, false
OWNER,            MODIFY, VIEW_DASHBOARD, true
USER(gene_admin), MODIFY, VIEW_DASHBOARD, true
EVERYBODY,        DELETE, VIEW_DASHBOARD, false
OWNER,            DELETE, VIEW_DASHBOARD, true
USER(gene_admin), DELETE, VIEW_DASHBOARD, true

// Tasks and jobs: Everybody can launch, see, stop, and erase a job.

// Application preferences: Everybody can access and modify them -- this is typically changed from the web client
// when the project is mature enough.

// Permissions: Only user 'gene-admin' is allowed to edit default rules and permission groups
EVERYBODY, MODIFY, APPLICATION_PERMISSIONS, false
USER(gene_admin), MODIFY, APPLICATION_PERMISSIONS, true
// Only user 'gene-admin' and the owner of an element are allowed to edit its permissions
EVERYBODY, PERMISSIONS, WORKSPACE, false
EVERYBODY, PERMISSIONS, SCENARIO, false
EVERYBODY, PERMISSIONS, VIEW_DASHBOARD, false
EVERYBODY, PERMISSIONS, TASK, false
EVERYBODY, PERMISSIONS, JOB, false
EVERYBODY, PERMISSIONS, APPLICATION_PREFERENCES, false
EVERYBODY, PERMISSIONS, APPLICATION_PERMISSIONS, false
USER(gene_admin), PERMISSIONS, WORKSPACE, true
USER(gene_admin), PERMISSIONS, SCENARIO, true
USER(gene_admin), PERMISSIONS, VIEW_DASHBOARD, true
USER(gene_admin), PERMISSIONS, TASK, true
USER(gene_admin), PERMISSIONS, JOB, true
USER(gene_admin), PERMISSIONS, APPLICATION_PREFERENCES, true
USER(gene_admin), PERMISSIONS, APPLICATION_PERMISSIONS, true
OWNER, PERMISSIONS, WORKSPACE, true
OWNER, PERMISSIONS, SCENARIO, true
OWNER, PERMISSIONS, VIEW_DASHBOARD, true
OWNER, PERMISSIONS, JOB, true

By default, a public workspace is created with the name Public Workspace. It is owned by user gene_admin. The following permission rules are included in the ruleset attached to it:

// Everybody has access on this public workspace, but nobody can delete it
EVERYBODY, ACCESS, WORKSPACE, true
EVERYBODY, DELETE, WORKSPACE, false
// Everybody has access to scenarios contained in the workspace, including for deletion
EVERYBODY, ACCESS, SCENARIO, true
EVERYBODY, DELETE, SCENARIO, true

As a result, the public workspace is shared in read-write mode, but cannot be deleted. Any other workspace is only accessible to its owner, with full privileges.

2.2. Defining Permission Groups

As described earlier, the permission system allows defining sets of rules for users and user roles. Those rules can apply across all the application elements, e.g. "All users with the MANAGER role can view all the Dashboards". Alternatively, they can be associated with permission groups, which in turn gather to specific application elements, e.g. "The permission group DOCTORS elements states that users with the CIVILIAN role cannot access any application element": this rule applies to application elements that are added to the DOCTORS elements permission group.

Specific exceptions can be defined individually for application elements; they will override rules from permission groups and the default rules. For example: "User Alice does not have the permission to ACCESS the Custom view Monthly KPIs".

3. Implementing Permission Samples

In this section, we review a number of use cases and propose an implementation in terms of permission rules.

3.1. Setting No Restriction

In this use case, all users are allowed to perform all operations on all application elements.

This can be implemented by defining no permission rule at all.

3.2. Hiding Application Elements

In the absence of any permission rule, all operations are allowed on any application element. Hiding an application element from a user, or a group of users, can be achieved by defining a permission rule that denies ACCESS permission on the application element. Indeed, all operations (except those related to permissions) require ACCESS: as a consequence, removing this permission bars access to all operations on the element.

3.2.1. Hiding All Tasks

In this use case, we assume that we have defined a user role named INTERN. We want to hide all tasks from users with this role, so that they cannot execute any processing.

This can be implemented by adding the following permission rule to the ruleset attached to the application.

role(INTERN), ACCESS, TASK, false

3.2.2. Hiding a Specific Task

In this use case, we want to hide only the task "Compute Plan" from users with role INTERN.

This can be implemented by adding the following permission rule to the ruleset attached to the task.

role(INTERN), ACCESS, TASK, false

This is the same rule as in the previous use case. However, the fact that it is put to the ruleset attached to task "Compute Plan", and not to the set of default rules, makes it applicable only to this task.

3.2.3. Hiding a Scenario

In this use case, we want to hide the scenario "Sensitive Data" from users with role INTERN.

This can be implemented by adding the following permission rule to the ruleset attached to the scenario.

role(INTERN), ACCESS, SCENARIO, false

3.2.4. Hiding a Workspace and its Scenarios

In this use case, we want to hide workspace "Sensitive Data Sets" from users with role INTERN, as well as all the scenarios that are contained in this workspace.

This can be implemented by adding the following permission rules to the ruleset attached to the workspace.

role(INTERN), ACCESS, WORKSPACE, false
role(INTERN), ACCESS, SCENARIO, false

The first rule denies access to the workspace. The second rule denies access to the scenarios, and will be found as part of the ruleset attached to the workspace that contains the scenario.

3.2.5. Hiding Various Elements

In this use case, we want to hide workspace "Sensitive Data Sets" from users with role INTERN, as well as all the scenarios that are contained in this workspace, and also the dashboard "Sensitive Design" and the task "Sensitive Planning".

This can be implemented by defining rules similar to the ones in the previous use cases on each of the application elements that we want to hide. However, a simpler implementation can be achieved using permission groups.

To this end, we first create a permission group named "Sensitive Things". We include the following elements in this group:

Workspace "Sensitive Data Sets"
Dashboard "Sensitive Design"
Task "Sensitive Planning"

and we add the following permission rules to the ruleset attached to this permission group:

role(INTERN), ACCESS, WORKSPACE, false
role(INTERN), ACCESS, SCENARIO, false
role(INTERN), ACCESS, VIEW_DASHBOARD, false
role(INTERN), ACCESS, TASK, false

These rules will be found as part of the ruleset attached to the group of the workspace, dashboard, and task; and as part of the ruleset attached to the workspace containing the scenarios.

Note that adding elements to the permission group can be done independently of, typically after, defining the permission rules in the attached ruleset.

3.2.6. Allowing Access to a Hidden Scenario

In this use case, we want to hide workspace "Sensitive Data Sets" from users with role INTERN, as well as all the scenarios that are contained in this workspace. Except for Noam, the CEO's child, who should have access to the scenario "Anonymized Sensitive Data" contained in this workspace; and for convenience, to the workspace as well.

This can be implemented by adding the following permission rules to the ruleset attached to the workspace.

role(INTERN), ACCESS, WORKSPACE, false
user(Noam), ACCESS, WORKSPACE, true
role(INTERN), ACCESS, SCENARIO, false

Then, add the following permission rule to the ruleset attached to the scenario "Anonymized Sensitive Data".

user(Noam), ACCESS, SCENARIO, true

These rules will work as in the previous use case for all users except Noam. The two rules with user pattern user(Noam) will have precedence for operations performed by Noam.

3.3. Setting Private Application Elements

In these use cases, instead of hiding elements from a set of users, we want to hide them from all users except a given set.

Imagine that we want the scenario "Sensitive Data" to only be visible to users with role MANAGER. This can be implemented by adding the following permission rules to the ruleset attached to the scenario:

EVERYBODY,     ACCESS, SCENARIO, false
role(MANAGER), ACCESS, SCENARIO, true

The first rule denies access to all users. The second, more specific rule, allows access to users with role MANAGER. As these rules are included in the ruleset attached to the scenario, they will only apply to this element.

All variations like the ones in the previous section on hiding elements can be replicated for private elements: a private task, a private workspace including its scenarios, a group of application elements of various types...

3.4. Restricting Operations

In this use case, we want all users to have access to a given workspace, but we want to prevent users with the INTERN role from modifying or deleting the workspace, or the scenarios it contains. Furthermore, we want that only users with role MANAGER be allowed to create a scenario in this workspace.

This can be implemented by adding the following permission rules to the ruleset attached to the workspace:

role(INTERN), MODIFY, WORKSPACE, false
role(INTERN), MODIFY, SCENARIO, false
role(INTERN), DELETE, WORKSPACE, false
role(INTERN), DELETE, SCENARIO, false
EVERYBODY,     CREATE, SCENARIO, false
role(MANAGER), CREATE, SCENARIO, true

3.5. Segmenting the Application

In this use case, our application allows its users to carry out two kinds of activities, let's say tactical planning and operational planning. To this end, it has a number of workspaces, dashboards, and tasks, dedicated to tactical planning, while other workspaces, dashboards, and tasks, are dedicated to operational planning. In addition, a few workspaces, dashboards, and tasks, are of interest regardless of the activity. We want some users to have only access to the application elements dedicated to one activity, some to the other, and some to both.

This can be implemented by first creating two roles in Keycloak, say TACTICAL and OPERATIONAL, and assigning these roles to users according to the elements they will be allowed to see. Users allowed to see elements related to both activities should be given both roles. Second, we should create two permission groups, say "Tactical Elements" and "Operation Elements". In each group, we will add the workspaces, dashboards, and tasks, related to the corresponding activity. Finally, we should add the following permission rules to the ruleset attached to the application permission group "Tactical Elements":

EVERYBODY, ACCESS, WORKSPACE, false
EVERYBODY, ACCESS, SCENARIO, false
EVERYBODY, ACCESS, VIEW_DASHBOARD, false
EVERYBODY, ACCESS, TASK, false
EVERYBODY, ACCESS, JOB, false
role(TACTICAL), ACCESS, WORKSPACE, true
role(TACTICAL), ACCESS, SCENARIO, true
role(TACTICAL), ACCESS, VIEW_DASHBOARD, true
role(TACTICAL), ACCESS, TASK, true
role(TACTICAL), ACCESS, JOB, true

Similar rules (with role(TACTICAL) replaced with role(OPERATIONAL)) should be added to the ruleset attached to the application permission group "Operational Elements".

With the rules above, the workspaces, dashboards, and tasks that belong to neither permission groups will be accessible to all users. This is fine in some applications, but not in others. If we are in an application where these general application elements must be accessible only to users with either role, then the following permission rules must be added to the ruleset attached to the application:

EVERYBODY, ACCESS, WORKSPACE, false
role(TACTICAL), ACCESS, WORKSPACE, true
role(OPERATIONAL), ACCESS, WORKSPACE, true
// same for SCENARIO, VIEW_DASHBOARD, TASK, and JOB