Policy Rule Constraints Examples

Last modified 22 Oct 2025 12:21 +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

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