<policyRule>
<!-- here we simply state that it's not possible to have active role with no description or no owner or no approver -->
<name>disallow-incomplete-role-activation</name>
<policyConstraints>
<presentation>
<message>
<key>AttemptToActivateIncompleteRole</key>
</message>
<importance>major</importance> <!-- this is a major cause; after 'clicking-through' the user could see details: that the role is incomplete, and the reason: no owner/approver or no description -->
</presentation>
<objectState>
<name>active lifecycleState</name>
<filter>
<q:text>lifecycleState = "active"</q:text>
</filter>
</objectState>
<or>
<name>incomplete-role</name>
<policySituation>...#incompleteRole</policySituation> <!-- we should provide policySituation specification also at the level of constraint -->
<!-- alternative 1 -->
<situationPersistence>full</situationPersistence> <!-- although there could be no incomplete active roles, we might want to report on e.g. incomplete roles in draft state -->
<triggerPersistence>user-information</triggerPersistence> <!-- we want to store user information only to conserve space -->
<!-- alternative 2 -->
<expectedUse>full-report</expectedUse>
<storageCompaction>full</storageCompaction>
<presentation>
<message>
<key>RoleIncomplete</key>
</message>
</presentation>
<minAssignees>
<!-- default importance is normal; and the constraint is self-explanatory, so no need to provide user information here -->
<multiplicity>1</multiplicity>
<relation>owner</relation>
<relation>approver</relation>
</minAssignees>
<objectState>
<name>no-description</name> <!-- we could also use some default mechanism to derive message keys, like policyConstraint.no-description -->
<filter>
<q:text>description not exists</q:text>
</filter>
</objectState>
</or>
</policyConstraints>
<policyActions>
<enforcement/>
</policyActions>
<evaluationTarget>focus</evaluationTarget>
</policyRule>
Using policy-driven information in workflows, certifications, notifications, reports, etc.
Information generated by policy rules are currently used at many places in midPoint:
Mechanism | Place | Information |
---|---|---|
approvals |
.. work item name .. work item 'additional information' (shown to approver) .. process name .. process 'additional information' (shown to approver or any other authorized user) |
.. reason why the given object or assignment modification is being approved - e.g. just because the role assignment needs to be approved, or because of SoD rule, or because some business rule (which one?) is not adhered to and requires manual confirmation .. more specific information related to the reason, e.g. … which roles are in SoD conflict with the one that is being assigned … specific values of items that are not correct .. any existing approvals/certifications issued so far: either just "who" and "valid to", or the whole record of related actions and their outcome. E.g. process or work item names could be: .. Approve modification of user XYZ (this is the most generic name) .. Approve activation of role XYZ (e.g. when lifecycle state is being set from "draft" to "active") .. Approve activation of role XYZ violating business rules BR123 and BR456 (e.g. when lifecycle state is being set to "active" but some rules are violated) |
enforcement |
.. GUI that shows the error message for attempted operation .. information for any other client (REST, SOAP, bulk action, …) that requested the attempted operation |
The same as above: what went wrong (SoD, business rule, …) and with what parameters. Maybe also related actions. (If e.g. some grace period expired.) |
approvals and enforcement preview |
.. when user clicks on "preview changes" in regular GUI .. when user inspects his role shopping cart |
The same as above: what went wrong (SoD, business rule, …) and with what parameters. Maybe also related actions.For approvals we could want to see preview of the approval process. |
certification |
.. certification work item: when reviewer wants to learn why given certification work item was presented to him .. certification campaign: when someone wants to see what is being certified in a given campaign (e.g. "this is campaign to certify SoD violation", or "this is campaign to certify violations of BR123 and BR456"). |
The same as above: what went wrong (SoD, business rule, …) and with what parameters. Maybe also related actions. |
notification |
Message sent to the user (in various formats: mail, SMS, …) |
The same as above: what went wrong (SoD, business rule, …) and with what parameters. Maybe also related actions. |
remediation |
This is a manual action, probably similar to an approval workflow. Maybe it will be the case management that will be used. |
The same as above: what went wrong (SoD, business rule, …) and with what parameters. Maybe also related actions. |
ad-hoc certification |
Ad-hoc certification campaign is started. So we want to learn about the reason either when reviewing a given work item or when we look at the whole campaign. |
The same as above: what went wrong (SoD, business rule, …) and with what parameters. |
reporting |
Reports on violations of business rules. |
From simple count and object/assignments lists that violate a specific business rule to detailed information on which business rule is broken and with what parameters. |
bulk action |
Synchronous or asynchronous execution of a bulk action. |
The same as above: what went wrong (SoD, business rule, …) and with what parameters. To be shown e.g. when looking at background task carrying out the bulk action. |
Notes:
-
All texts (process and work item names, process and work items additional information, enforcement error messages, …) must be localizable.
How to specify the information to be conveyed to users? From the most specific to most generic ways:
Level | Mechanism | Examples |
---|---|---|
1 |
channel-specific facilities |
using generic/custom notifiers (defined in system configuration) |
2 |
policy action specific configuration |
additionalInformation expression in approval stage definitioncustom message definition in enforcement action (not yet implemented)approvalDisplayName in process specification or approval action itself |
3 |
generic or specific information added to policy rule and/or individual constraints |
constraint or policy rule name/description - like "trying to activate role without an owner"some "localizable user message" with optional parameters (defined by expressions) to either policy rule or a key constraint (not yet implemented) |
4 |
built-in knowledge about constraints |
SoD (exclusion) constraints have knowledge of targets that are excluded; so we just want to convey information on these when dealing with exclusion informationmin/max assignees constraints again have all the information we need to show |
According to the best midPoint traditions we prefer 4 before 3 before 2 before 1.
TODO write detailed information here
Approval display name, i.e. something that is put into work item names, approval process instance names and approval task names, is derived from (first one that exists applies):
-
policyActions/approval/processSpecification/approvalDisplayName
-
policyActions/approval/approvalDisplayName (considered in the order of approval actions application, directed by compositionSpecification)
-
policyConstraints/(constraint)/presentation/shortMessage
If default
is used as a key name in the message being applied it means that the default message (e.g. Assigning role "A" to user "U", Modifying assignment of org "O" on user "U", etc.)
Some examples
TODO
Some ideas
presentation element on policy constraints
Item | Meaning | Example |
---|---|---|
message |
Message to be conveyed to the user. It is a LocalizableMessage (or equivalent), having key, parameters, and fallbackMessage. |
todo |
shortMessage |
Very short message describing the situation. Could be used for e.g. notification messages subject, approval process or work item names. TODO. Again, a LocalizableMessage. |
todo |
longMessage |
(TODO better name) - long, documentation-like explanation of the rule |
|
importance |
How important is this particular information. E.g. major, normal, minor, none (or should we use numbers to provide more flexibility?). By default, only the highest-level messages are shown. If requested, user could view also lower-level messages. |
todo |
Alternative 1: Persistence
Triggers and situations take storage place and processing time when maintaining. So they are made configurable with regards to their storage using the following two parameters of policy constraints:
Item | Meaning | Values |
---|---|---|
situationPersistence |
Should the situation stemming from this constraint be persistently stored? |
full, none |
triggerPersistence |
Should the trigger stemming from this constraint be persistently stored? |
full, user-information, user-information-highest, none |
Alternative 2: Expected use
Value of expectedUse property | Meaning | |
---|---|---|
certification |
Situation and triggers will be stored. |
|
brief-report |
Situation will be stored but no triggers. |
|
full-report |
Situation and triggers will be stored. |
Storage conservation (if triggers are to be stored)
Value of storageCompaction property | Meaning |
---|---|
full |
Only message and short message will be stored. |
normal |
Whole triggers will be stored. (But only those that are directly marked with expectedUse property.) |
none |
Whole triggers will be stored, including subtriggers. |
An example
Another example - a policy rule attached to roles that could not be assigned to users from cost centers 1900-1999 without special approval:
<policyRule>
<name>approval-for-cc-19xx</name>
<description>Assignment of this role to users from cost centers 1900-1999</description>
<policyConstraints>
<objectState>
<name>cc-19xx</name>
<presentation>
<message>
<key>AssignmentToUserFromWrongCostCenter</key> <!-- e.g. attempt to assign role {0} to a user from cost center {1} (in the range of 1900-1999) -->
<param>
<index>0</index>
<source>
<path>$target/name</path>
</source>
</param>
<param>
<index>1</index>
<source>
<path>$focus/costCenter</path>
</source>
</param>
</message>
<importance>major</importance>
</presentation>
<filter>
<q:text>costCenter greater "1900" and costCenter less "1999"</q:text>
</filter>
</objectState>
</policyConstraints>
<policyActions>
<approval>
<!-- ... -->
</approval>
</policyActions>
</policyRule>