Policy Rules Examples

Last modified 17 Jul 2026 10:25 UTC
Since 4.9
This functionality is available since version 4.9.

This page lists practical policy rule examples, and supplements the examples shown in Policy Configuration.

Recompute Users After Org Change

The following example triggers recomputation of all users in an org when there is a change in the org.

<policyRule>
    <name>recompute-user-on-change-partner-status</name>
    <policyConstraints>
        <modification/>
    </policyConstraints>
    <policyActions>
        <scriptExecution>
            <object>
                <linkSource>
                    <type>UserType</type>
                </linkSource>
            </object>
            <executeScript>
                <s:recompute>
                    <s:triggered>
                        <safetyMargin>PT1M</safetyMargin>
                        <fireAfter>PT5M</fireAfter>
                    </s:triggered>
                </s:recompute>
            </executeScript>
        </scriptExecution>
    </policyActions>
</policyRule>

Recompute Users After User Change

The following example triggers recomputation when a user is modified.

<policyRule>
    <name>recompute-user-on-change</name>
    <policyConstraints>
        <modification>
            <operation>modify</operation>
        </modification>
    </policyConstraints>
    <policyActions>
        <scriptExecution>
            <object>
                <currentObject/>
            </object>
            <executeScript>
                <s:recompute>
                    <s:triggered>
                        <safetyMargin>PT1M</safetyMargin>
                        <fireAfter>PT5M</fireAfter>
                    </s:triggered>
                </s:recompute>
            </executeScript>
        </scriptExecution>
    </policyActions>
</policyRule>

Limiting the Number of Users

The following policy rule limits the number of users of a licensed resource to 5:

<policyRule>
    <name>Limit number of assigned licenses</name>
    <policyConstraints>
        <maxAssignees>
            <multiplicity>5</multiplicity>
        </maxAssignees>
    </policyConstraints>
    <policyActions>
        <enforcement/>
    </policyActions>
</policyRule>

Prevent Role Assignment

In this example, we are preventing users from being assigned to a role if either of the following is true:

  • They already have a forwarding email address set, i.e. forwardEmailAddress is not null.

  • They are already assigned a role named perm.m365license.all or perm.m365license.exchange.

This only applies to users who do not have the 4eb82ce9-cf90-4e8d-ab53-121bb676c756 archetype.

If the policy is violated, the assignment is pruned (removed), and a message is shown for the exclusion case.

<assignment>
    <policyRule>
        <name>excluded-role</name>
        <policyConstraints>
            <name>excluded-role-constraint</name>
            <or>
                <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>
                <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>
            </or>
        </policyConstraints>
        <evaluationTarget>assignment</evaluationTarget>
        <policyActions>
            <prune/>
        </policyActions>
    </policyRule>
    <condition>
        <expression>
            <script>
                <code>
                    boolean returnValue = false
                    if(focus!=null){
                        returnValue = !midpoint.hasArchetype(focus, "4eb82ce9-cf90-4e8d-ab53-121bb676c756")
                    }
                    return returnValue

                </code>
            </script>
        </expression>
    </condition>
</assignment>

The following example shows a global policy rule that excludes roles assigned to users based on the forwardEmailAddress attribute null check.

<globalPolicyRule>
    <name>Global policy rule for exclude roles</name>
    <policyConstraints>
        <and>
            <hasAssignment>
                <targetRef relation="org:default" type="c:RoleType">
                    <filter>
                        <q:text>name = 'accessRole1' or name = 'accessRole2'</q:text>
                    </filter>
                    <resolutionTime>run</resolutionTime>
                </targetRef>
            </hasAssignment>
            <modification>
                <operation>modify</operation>
            </modification>
        </and>
    </policyConstraints>
    <policyActions>
        <scriptExecution>
            <object>
                <currentObject/>
            </object>
            <executeScript xmlns:s="http://midpoint.evolveum.com/xml/ns/public/model/scripting-3">
                <s:unassign>
                    <s:filter>
                        <q:text>targetRef = ```
                            import com.evolveum.midpoint.schema.util.ObjectTypeUtil
                            import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType

                            ObjectTypeUtil.createObjectRef(midpoint.searchObjectByName(RoleType,"accessRole1").getOid())
                            ```
                            or targetRef = ```
                            import com.evolveum.midpoint.schema.util.ObjectTypeUtil
                            import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType

                            ObjectTypeUtil.createObjectRef(midpoint.searchObjectByName(RoleType,"accessRole2").getOid())
                            ```
                        </q:text>
                    </s:filter>
                </s:unassign>
            </executeScript>
        </scriptExecution>
    </policyActions>
    <focusSelector>
        <type>UserType</type>
        <archetypeRef oid="00000000-0000-0000-0000-000000000702" relation="org:default" type="c:ArchetypeType"/>
    </focusSelector>
    <condition>
        <source>
            <path>extension/myAttribute</path>
        </source>
        <expression>
            <script>
                <code>
                    return myAttribute!=null
                </code>
            </script>
        </expression>
    </condition>
<globalPolicyRule>

Time-limited role assignment

The following example policy enforces time-limited assignments for selected roles. Whenever a user is assigned to a role that is governed by this policy, the assignment is automatically constrained to a fixed validity period - 4 hours in this example.

In effect, this policy ensures that any assignment to selected roles is automatically temporary, without requiring manual input from administrators or users.

This can be useful in scenarios where certain roles should only be granted for a limited time, such as emergency admin DB access or temporary access for external contractors.

The example below finds archetypes that have the policy assigned. Then, when a new role assignment is added to a user, it checks if that role belongs to one of those archetypes. If it does and the assignment has not been processed yet, it sets its validity to 4 hours and adds a process description to prevent repetitive validity changes.

Policy rule that limits the validity of assignments to 4 hours
<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" oid="488399b2-4679-461c-afc0-1f70aaa7456e">
    <name>assignment-limited-to-4-hours</name>
    <activation/>
    <displayName>Assignment limited to 4 hours</displayName>
    <inducement>
        <identifier>assignment-limited-to-4-hours</identifier>
        <policyRule>
            <name>assignment-limited-to-4-hours</name>
            <description>
                Policy rule triggered when new user assignments are added.
                The scripted action sets the validity period and process description for user assignments that meet the following criteria:
                - The targetRef OID is in the list of TargetRef OIDs that triggered the action.
                - The targetRef OID belongs to a role connected to the policy (role → archetype → policy).
                - The assignment has not been processed yet.
            </description>
            <policyConstraints>
                <assignment>
                    <name>Add assignment constraint</name>
                    <operation>add</operation>
                </assignment>
            </policyConstraints>
            <policyActions>
                <scriptExecution>
                    <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><![CDATA[
                                        import com.evolveum.midpoint.prism.equivalence.EquivalenceStrategy
                                        import com.evolveum.midpoint.xml.ns._public.common.common_3.ArchetypeType
                                        import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType
                                        import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType

                                        // Adjust to your needs
                                        def VALIDITY_PERIOD = "PT4H"
                                        // Informational purpose + Needed to prevent repetitive validity change
                                        // in case an assignment to the same role already exists
                                        def PROCESS_DESCRIPTION = "Validity automatically adjusted!"

                                        // Fetch assignments that were added and have triggered the policy rule
                                        def primaryDelta = modelContext?.getFocusContext()?.getPrimaryDelta()
                                        if (primaryDelta == null) {
                                            return
                                        }
                                        def assignmentDelta = primaryDelta.findContainerDelta(UserType.F_ASSIGNMENT)
                                        if (assignmentDelta == null) {
                                            return
                                        }

                                        // Clone the input user object used to create the final delta
                                        def user = input
                                        def userBefore = user.clone()

                                        // Fetch all archetypes connected to the policy
                                        def archetypeQuery = midpoint.queryFor(
                                                ArchetypeType,
                                                "assignment/targetRef matches (oid = '488399b2-4679-461c-afc0-1f70aaa7456e')")
                                        def connectedArchetypes = midpoint.searchObjects(archetypeQuery)
                                        def connectedArchetypesOIDs = connectedArchetypes.collect { it.oid }

                                        // Filter only those assignment role oids that are directly connected to the archetypes
                                        // (In case of adding multiple assignments in one operation,
                                        // there can be present non-relevant assignments)
                                        def relevantAssignmentsOIDs = []
                                        assignmentDelta.getValuesToAdd().each {
                                            if (it.asContainerable().targetRef?.type == RoleType.COMPLEX_TYPE) {
                                                def targetRole = midpoint.getObject(RoleType.class, it.asContainerable().targetRef?.oid)
                                                if (connectedArchetypesOIDs.intersect(targetRole?.archetypeRef?.oid)) {
                                                    relevantAssignmentsOIDs.add(it.asContainerable().targetRef?.oid)
                                                }
                                            }
                                        }

                                        // Set validity period and process description to all relevant user assignments
                                        // (Relevant assignments do not have the process description yet
                                        // and their role oids are present in the filtered oids from the previous step)
                                        user.assignment.each {
                                            if (relevantAssignmentsOIDs.contains(it.targetRef.oid)
                                                    && it.description != PROCESS_DESCRIPTION) {
                                                it.activation.setValidTo(basic.fromNow(VALIDITY_PERIOD))
                                                it.setDescription(PROCESS_DESCRIPTION)
                                            }
                                        }

                                        // Modify user
                                        def delta = userBefore
                                                .asPrismObject()
                                                .diff(user.asPrismObject(), EquivalenceStrategy.IGNORE_METADATA)
                                        midpoint.modifyObject(delta)
                                    ]]></code>
                                </s:value>
                            </s:parameter>
                        </s:action>
                    </executeScript>
                </scriptExecution>
            </policyActions>
        </policyRule>
        <order>2</order>
        <focusType>UserType</focusType>
    </inducement>
</policy>
Was this page helpful?
YES NO
Thanks for your feedback