Policy Rule Constraints Examples

Last modified 21 Apr 2026 07:57 +02:00

This page presents examples of policy rule constraints.

Refer to policy rule constraints for details on individual constraints.

objectState

Example
<policyConstraints>
    <objectState>
        <name>fwEmailValidation</name>
        <expression>
            <script>
                <code>
                    boolean returnValue = false
                    if (basic.getExtensionPropertyValue(user, "http://example.org/midpoint", "forwardEmailAddress") != null) {
                        returnValue = true
                    }
                    return returnValue
                </code>
            </script>
        </expression>
    </objectState>
</policyConstraints>
Example
<policyConstraints>
    <objectState>
        <name>active lifecycleState</name>
        <filter>
            <q:text>lifecycleState = "active"</q:text>
        </filter>
    </objectState>
</policyConstraints>

assignmentState

Example
<policy xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
        xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3"
        xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3" xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"
        xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        oid="f6e27725-c148-4ef3-8bef-9404d67ca1e8">
    <name>assignmentState-policy</name>
    <activation/>
    <displayName>Assignment State Policy</displayName>
    <inducement id="75">
        <policyRule>
            <name>Assignment State Policy Rule</name>
            <policyConstraints>
                <assignmentState>
                    <expression>
                        <script>
                            <code>import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationStatusType
                            log.info("ASSIGNMENT STATUS: " + assignment)
                            log.info("USER OBJECT: " + object)
                            if (assignment?.activation?.effectiveStatus == null) {
                                return false
                            }
                            return assignment.activation.effectiveStatus == ActivationStatusType.DISABLED
                            </code>
                        </script>
                    </expression>
                </assignmentState>
            </policyConstraints>
            <policyActions>
                <scriptExecution id="8">
                    <executeScript xmlns:s="http://midpoint.evolveum.com/xml/ns/public/model/scripting-3">
                        <s:action>
                            <s:type>execute-script</s:type>
                            <s:parameter>
                                <s:name>script</s:name>
                                <s:value xsi:type="c:ScriptExpressionEvaluatorType">
                                    <code>
                                        log.info("User has disabled assignment for this role: " + input)
                                    </code>
                                </s:value>
                            </s:parameter>
                        </s:action>
                    </executeScript>
                </scriptExecution>
        </policyActions>
        </policyRule>
    </inducement>
</policy>

hasAssignment

Example
<policyConstraints>
    <hasAssignment>
        <targetRef relation="org:default" type="c:RoleType">
            <filter>
                <q:text>name = 'accessRole1' or name = 'accessRole2'</q:text>
            </filter>
            <resolutionTime>run</resolutionTime>
        </targetRef>
    </hasAssignment>
</policyConstraints>

hasNoAssignment

Example
<policyConstraints>
    <hasNoAssignment>
        <presentation>
            <message>
                <fallbackMessage>NDA required</fallbackMessage>
            </message>
        </presentation>
        <!-- NDA clearance -->
        <targetRef oid="09360ff0-d506-4751-b13f-4e01422693ac" type="RoleType" />
    </hasNoAssignment>
</policyConstraints>

requirement

Example
<policyConstraints>
    <requirement>
        <!-- NDA clearance -->
        <targetRef oid="09360ff0-d506-4751-b13f-4e01422693ac" type="PolicyType" />
    </requirement>
</policyConstraints>

exclusion

Example
<policyConstraints>
    <name>excluded-role-constraint</name>
        <exclusion>
            <targetRef type="RoleType">
                <filter>
                    <q:text>name = 'perm.m365license.all' or name = 'perm.m365license.exchange'</q:text>
                </filter>
                <resolutionTime>run</resolutionTime>
            </targetRef>
            <presentation>
                <message>
                    <fallbackMessage>Violation: perm.m365license roles are assigned for active users, could not be assigned for this user.</fallbackMessage>
                </message>
            </presentation>
        </exclusion>
</policyConstraints>

minAssignees

Example
<policyConstraints>
    <minAssignees>
        <name>constraint-require-approver</name>
        <multiplicity>1</multiplicity>
        <relation>org:approver</relation>
    </minAssignees>
</policyConstraints>

maxAssignees

Example
<policyConstraints>
    <maxAssignees>
        <multiplicity>5</multiplicity>
    </maxAssignees>
</policyConstraints>

modification

The modification constraint triggers when one of the following operations is executed:

  • add - A new object is being added, i.e., created in midPoint.

  • modify - An existing object is being modified in midPoint.

  • delete - An existing object is being deleted from midPoint.

If you specify more than one operation, the constraint will trigger if any of the specified operations is executed. If you do not specify an operation, the constraint will trigger for all operations.

You can narrow down the operations using the following elements:

  • item - Defines which item of the object the operation applies to, irrespective of whether the item is being added, modified, or deleted. The constraint triggers for the combination of the operation and the item.
    For example, if you specify the add operation and the emailAddress item, the constraint will trigger only if an object with an emailAddress item is being added. It will not trigger when adding emailAddress to an existing object, or when modifying or deleting emailAddress of an existing object.

    <modification>
        <operation>add</operation>
        <item>emailAddress</item>
    </modification>
  • exactPathMatch - If set to true, items paths to be matched must match exactly. For example, if an inducement is specified as an item to be matched, only modifications with and inducement in the path (i.e., the whole inducement that is being added, modified, or deleted) will match.
    Used only if item is set to modify. For add and delete operations, exactPathMatch is ignored. The default value is false.

  • specialItem - A supplement to item that specifies special items that cannot be described using a regular item path. This is supported for MODIFY deltas only. The following values are valid:

    • resourceObjectNamingAttribute - The naming attribute of the resource object that is being modified.

    • resourceObjectIdentifier - A primary or secondary identifier of the resource object that is being modified.

    • resourceObjectEntitlement - An entitlement of the resource object that is being modified.

    • resourceObjectItem - Any item on the resource object that is being modified.

    If you define more than one value, all of them have to match.

  • expression - Expression that is used to determine the result. This is evaluated in addition to all other conditions, and it must be true for the constraint to trigger.

    Expression example
    <expression>
        <script>
            <code>return true</code>
        </script>
    </expression>
Modification example
<mark xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
      xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
    oid="24e42ec5-ee5d-41b8-9b36-295b3800b469">
    <name>LDAP account modified</name>
    <assignment>
        <targetRef oid="00000000-0000-0000-0000-000000000700" type="ArchetypeType"/> <!-- event mark -->
    </assignment>
    <displayOrder>900</displayOrder> <!-- show this mark at the end -->
    <policyRule>
        <policyConstraints>
            <objectState>
                <filter>
                    <q:text>resourceRef matches (oid = '32531590-4606-4333-9cc2-0faa1ae68509')</q:text> <!-- LDAP -->
                </filter>
            </objectState>
            <or> <!-- copied from "resource object affected" event mark -->
                <modification>
                    <operation>modify</operation>
                    <specialItem>resourceObjectItem</specialItem>
                </modification>
                <modification>
                    <!-- We assume that ADD/DELETE always modifies the state of the resource -->
                    <operation>add</operation>
                    <operation>delete</operation>
                </modification>
            </or>
        </policyConstraints>
        <evaluationTarget>projection</evaluationTarget>
    </policyRule>
</mark>

assignment

Example
<policyRule>
    <name>approval-by-security-team</name>
    <policyConstraints>
        <assignment>
            <scope>any</scope>
        </assignment>
    </policyConstraints>
    <policyActions>
        <approval>
            <compositionStrategy>
                <order>120</order>
            </compositionStrategy>
            <approvalSchema>
                <stage>
                    <name>Security</name>
                    <approverRef oid="293fe73e-472a-11ea-b04f-274374b2c5e2" type="OrgType"/>
                    <evaluationStrategy>firstDecides</evaluationStrategy>
                    <groupExpansion>onWorkItemCreation</groupExpansion>
                    <outcomeIfNoApprovers>reject</outcomeIfNoApprovers>
                </stage>
            </approvalSchema>
        </approval>
    </policyActions>
</policyRule>

situation

Example
<globalPolicyRule>
    <name>sod-approval</name>
    <description>Approval action for (existing) exclusion violations</description>
    <policyConstraints>
        <situation>
            <situation>http://midpoint.evolveum.com/xml/ns/public/model/policy/situation#exclusionViolation</situation>
        </situation>
    </policyConstraints>
    <policyActions>
        <approval>
            <compositionStrategy>
                <order>30</order>
            </compositionStrategy>
            <approvalSchema>
                <stage>
                    <name>SoD</name>
                    <approverRef type="OrgType">
                        <filter>
                            <q:equal>
                                <q:path>name</q:path>
                                <q:value>SoD Approvers</q:value>
                            </q:equal>
                        </filter>
                        <resolutionTime>run</resolutionTime>
                    </approverRef>
                    <evaluationStrategy>firstDecides</evaluationStrategy>
                    <groupExpansion>onWorkItemCreation</groupExpansion>
                </stage>
            </approvalSchema>
        </approval>
    </policyActions>
    <focusSelector>
        <type>UserType</type>
    </focusSelector>
    <targetSelector>
        <!-- no need to filter on subtype, as each role has to have SoD defined -->
        <type>RoleType</type>
    </targetSelector>
</globalPolicyRule>

custom

Example
<mark xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
    oid="00000000-0000-0000-0000-000000000730">
    <name>Projection activated</name>
    <description>Operation that activated the projection</description>
    <documentation>
        This is an operation that brought the projection into existence and being effectively enabled.
        (So, previously it was either non-existent or effectively disabled.)
    </documentation>
    <assignment id="1">
        <identifier>archetype</identifier>
        <targetRef oid="00000000-0000-0000-0000-000000000700" type="ArchetypeType"/>
    </assignment>
    <displayOrder>300</displayOrder>
    <policyRule id="2">
        <name>projection-activated</name>
        <policyConstraints>
            <custom id="3">
                <name>$projection-activated</name>
                <expression>
                    <script>
                        <code>midpoint.currentProjectionActivated</code>
                    </script>
                </expression>
            </custom>
        </policyConstraints>
        <evaluationTarget>projection</evaluationTarget>
    </policyRule>
</mark>
Example
<mark xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
    oid="e2dccf40-9bfd-42a1-aa02-48b0f31cdb1c">
    <name>nonsense-mark</name>
    <description>Always fails. Used to check the exclusion mechanism.</description>
    <assignment>
        <targetRef oid="00000000-0000-0000-0000-000000000700" type="ArchetypeType"/>
    </assignment>
    <policyRule>
        <policyConstraints>
            <custom>
                <expression>
                    <script>
                        <code>throw new UnsupportedOperationException("nonsense mark")</code>
                    </script>
                </expression>
            </custom>
        </policyConstraints>
        <focusSelector>
            <type>UserType</type>
        </focusSelector>
    </policyRule>
</mark>

collectionStats

Example
<policyRule>
    <policyConstraints>
        <collectionStats>
            <collection>
                <interpretation>explicit</interpretation>
            </collection>
        </collectionStats>
    </policyConstraints>
    <policySituation>#resourceHealthDanger</policySituation>
    <policyThreshold>
        <highWaterMark>
            <percentage>99.9</percentage>
        </highWaterMark>
    </policyThreshold>
</policyRule>

alwaysTrue

Example
<policyConstraints>
    <alwaysTrue/>
</policyConstraints>

orphaned

Example
<globalPolicyRule>
    <policyConstraints>
        <orphaned/>
    </policyConstraints>
    <policySituation>http://midpoint.evolveum.com/xml/ns/public/model/policy/situation#orphaned</policySituation>
    <policyActions>
        <record/>
    </policyActions>
    <focusSelector>
        <type>TaskType</type>
    </focusSelector>
</globalPolicyRule>

See Orphaned Tasks for more examples of the orphaned constraint.

and

Example
<policyConstraints>
    <and>
        <hasAssignment>
            ...
        </hasAssignment>
        <modification>
            ...
        </modification>
    </and>
</policyConstraints>
Example - require at least 2 approvers for high-risk roles
<and>
    <name>less-than-2-approvers-for-high-risk-role</name>
    <objectState>
        <name>high-risk-role</name>
        <filter>
            <q:text>riskLevel = "high"</q:text>
        </filter>
    </objectState>
    <objectMinAssigneesViolation>
        <multiplicity>2</multiplicity>
        <relation>approver</relation>
    </objectMinAssigneesViolation>
</and>

or

Example
<policyConstraints>
    <name>excluded-role-constraint</name>
    <or>
        <objectState>
            ...
        </objectState>
        <exclusion>
            ...
        </exclusion>
    </or>
</policyConstraints>

not

Example
<policyConstraints>
    <objectState>
        <name>ot-high-risk-role</name>
        <filter>
            <q:not>
                <q:path>riskLevel</q:path>
                    <q:value>high</q:value>
                </q:equal>
            </q:not>
        </filter>
    </objectState>
</policyConstraints>

transition

In the following example, for the policy rule action to trigger, the filter in the constraint must evaluate to false before making changes to the lifecycleState attribute, and true after the change.

Example
<policy xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
        xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3" xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3"
        xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3" xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"
        xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        oid="7f4cba75-9a16-47d6-995b-69963b962504">
    <name>cannot-change-lifecycle-to-active-policy</name>
    <activation/>
    <displayName>Cannot Change LifeCycle To Active Policy</displayName>
    <inducement id="75">
        <policyRule>
            <name>cannot-change-lifecycle-</name>
            <policyConstraints>
                <transition>
                    <name>role-switched-to-active</name>
                    <stateBefore>false</stateBefore>
                    <stateAfter>true</stateAfter>
                    <constraints>
                        <objectState>
                            <name>active lifecycleState</name>
                            <filter>
                                <q:text>lifecycleState = "active"</q:text>
                            </filter>
                        </objectState>
                    </constraints>
                </transition>
            </policyConstraints>
            <policyActions>
                <enforcement/>
            </policyActions>
        </policyRule>
    </inducement>
</policy>

ref

Example - forbidding activation of incomplete roles, and allowing activation (requires approval) of complete roles
<inducement>
    <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>
            <objectState>
                <name>active lifecycleState</name>
                <filter>
                    <q:text>lifecycleState = "active"</q:text>
                </filter>
            </objectState>
            <or>
                <name>incomplete-role</name>
                <minAssignees>
                    <multiplicity>1</multiplicity>
                    <relation>owner</relation>
                    <relation>approver</relation>
                </minAssignees>
                <objectState>
                    <name>no description</name>
                    <filter>
                        <q:text>description not exists</q:text>
                    </filter>
                </objectState>
            </or>
        </policyConstraints>
        <policyActions>
            <enforcement/>
        </policyActions>
        <evaluationTarget>focus</evaluationTarget>
    </policyRule>
</inducement>
<inducement>
    <policyRule>
        <name>approve-role-activation</name>
        <policyConstraints>
            <transition>
                <name>role-switched-to-active</name>
                <stateBefore>false</stateBefore>
                <stateAfter>true</stateAfter>
                <constraints>
                    <ref>active lifecycleState</ref>
                </constraints>
            </transition>
        </policyConstraints>
        <policyActions>
            <approval>
                <compositionStrategy>
                    <order>10</order>
                </compositionStrategy>
                <approverRelation>owner</approverRelation>
            </approval>
        </policyActions>
    </policyRule>
</inducement>
Was this page helpful?
YES NO
Thanks for your feedback