Skip to main content
Skip table of contents

Object Policies

Definition

An Object Policy is an Identity Management Service Policy allowing to execute arbitrary actions on Managed Objects, either on a scheduled basis, or in reaction to an Object Operation.

Object Policies are primarily composed of a mode (Scheduled or Event), a Scope, and a list of actions. They may leverage Reporting Data to further restrict their scope, and also act on secondary Objects. For instance, an Object Policy acting on Organizations may define actions to be executed on some (if not all) Identities belonging to said Organizations.

Configuration

You can access the Object Policy configuration :

  • by clicking on "Policies" â†’ “Object Policy”

  • by clicking on "System" â†’ "Configurations" → "Data Model" and perform an import/export.

Properties

Property name

Type

Mandatory

Description

Values (default value in bold)

id

String

YES

The unique identifier of the Object Policy.

It is case sensitive and no special characters (except - or _) are allowed.

Must be between 1 and 64 characters long.

-

name

String

YES

The Object Policy name.

The name may be different from the identifier.Specifying the name first allows to define automatically the identifier.
Must be between 2 and 128 characters long.

-

description

String

NO

Allows to describe the purpose of the Object Policy.

Must be at most 1024 characters long.

-

active

Boolean

YES

Allows to define if the Object Policy is activated or not.

true, false

activation

Enum

YES

The Activation Mode of this policy

  • In EVENT mode, the actions will be executed when an operation occurs on an object matching the Policy Scope

  • In SCHEDULED mode, the actions will be executed on a scheduled basis for all objects matching the Policy Scope, according to the Execution Plan

EVENT, SCHEDULED

handleEvent

RuleDefinition

NO

A test Rule to decide whether to handle the current event (can only be used in EVENT mode)

-

scope

Static Object Scope

YES

Allows to configure on which Objects the Object Policy will be applied.

It is possible to define several Object Types.

-

reportingScope

Static Reporting Scope

NO

An optional correlation constraint on Reporting data, complementing the Object Scope.

-

actions

List<RuleDefinition>

NO

The Actions to execute on Objects

-

handleSecondaryScope

RuleDefinition

NO

A test Rule to decide whether to handle the secondary Scope

-

secondaryScope

Dynamic Object Scope

NO

An optional secondary scope, that will be resolved and processed for each “primary” object

-

secondaryReportingScope

Dynamic Reporting Scope

NO

An optional correlation constraint on Reporting data, complementing the Secondary Object Scope.

-

secondaryActions

List<RuleDefinition>

NO

The Actions to execute on secondary Objects

-

pageSize

Integer

NO

Used to indicate how many objects can be processed in a batch by actions (SCHEDULED mode and Secondary Scope processing)

10 or more

executionPlan

Execution Plan

Only in SCHEDULED mode

In SCHEDULED mode, the Policy scheduling Configuration.

-

Reporting Scope

As Object and Simple Scopes, Reporting Scopes may be Static or Dynamic. A Static (resp. Dynamic) scope embeds a Static (resp. Dynamic) Simple scope.

Property name

Type

Mandatory

Description

Values (default value in bold)

reportingObjectConfigurationId

String

YES

The reporting Collection on which correlation should be performed

-

correlationMode

Enum

YES

The correlation mode:

  • POSITIVE: Actions will be executed if and only if at least one correlated Reporting Document is found

  • NEGATIVE: Actions will be executed if and only if no correlated Reporting Document is found

POSITIVE, NEGATIVE

scope

Simple Scope

YES

The search Scope of reporting Documents

-

imCorrelationAttribute

String

YES

The Object Attribute to use for correlation

id

imCorrelationAttribute

String

YES

The Reporting Document property path to use for correlation

_id

Examples

Simple Scheduled Policy

Soft delete identities that were disabled more than 35 days ago
XML
<ctdidm:ObjectPolicy id="delete_identity_35D">
    <createdAt>2021-03-08T15:34:10.461Z</createdAt>
    <name>Delete identity - IDE-TB2B-RGL-05</name>
    <description>35 days after invalidation of an identity, set its status to deleted</description>
    <activation>SCHEDULED</activation>
    <pageSize>50</pageSize>
    <executionPlan>
        <scheduleType>CRON</scheduleType>
        <cron>0 0 22 ? * * *</cron>
        <interval>0</interval>
        <timeZone>Europe/Paris</timeZone>
    </executionPlan>
    <active>true</active>
    <scope type="EXPRESSION" objectKind="IDENTITY">
        <searchExpression>
            <search:And>
              <search:Prop op="EQUALS" name="status">
                  <value script="false">NORMAL</value>
              </search:Prop>
              <search:Prop op="EQUALS" name="enabled">
                  <value script="false">false</value>
              </search:Prop>
              <search:Prop op="EQUALS" name="identityOwner">
                  <value script="false">MKA</value>
              </search:Prop>
              <search:Prop op="IS_NOT_NULL" name="_disabledAt"/>
              <search:Not>
                  <search:Prop op="IN_LAST" name="_disabledAt">
                    <value script="false">P35D</value>
                  </search:Prop>
              </search:Not>
            </search:And>
        </searchExpression>
        <objectTypes>
          <objectType>b2bUser</objectType>
        </objectTypes>
    </scope>
    <actions>
        <action>
          <script><![CDATA[
ObjectOperationOptions options = new ObjectOperationOptions()
options.validationStrategy(ObjectOperationOptions.ValidationStrategy.BYPASS)

MANAGE.newPatch()
	.set("status").value(ObjectStatus.DELETED)
	.patch(OBJECT, options)									
return ActionOutcome.success()
			]]></script>
        </action>
    </actions>
  </ctdidm:ObjectPolicy>

Reporting Scope

Disable identities that did not authenticate in the last 365 days
XML
<ctdidm:ObjectPolicy id="identity-user-delete-job"
                     xmlns:ctdidm="http://www.memority.com/citadel/idm/1_0"
                     xmlns:search="http://www.memority.com/toolkit/search-expression/1_0">
    <name>identity-user-delete-job</name>
    <activation>SCHEDULED</activation>
    <pageSize>10</pageSize>
    <executionPlan>
        <scheduleType>CRON</scheduleType>
        <cron>0 40 2 1/1 * ? *</cron>
        <interval>0</interval>
        <timeZone>Europe/Paris</timeZone>
    </executionPlan>
    <active>true</active>
    <scope type="EXPRESSION" objectKind="IDENTITY">
        <searchExpression>
            <search:And>
                <search:Prop name="status" op="EQUALS">
                    <value script="false">NORMAL</value>
              </search:Prop>
                <search:Prop name="enabled" op="EQUALS">
                    <value script="false">true</value>
                </search:Prop>
            </search:And>
        </searchExpression>
        <objectTypes>
          <objectType>user</objectType>
        </objectTypes>
    </scope>
    <reportingScope>
        <imCorrelationAttribute>id</imCorrelationAttribute>
        <reportingCorrelationAttribute>_id</reportingCorrelationAttribute>
        <reportingObjectConfigurationId>reporting-identity-details</reportingObjectConfigurationId>
        <correlationMode>NEGATIVE</correlationMode>
        <scope>
            <searchExpression>
                <search:Prop name="lastAuthent" op="IN_LAST">
                    <value script="false">P365D</value>
                </search:Prop>
            </searchExpression>
        </scope>
    </reportingScope>
    <actions>
        <action>
            <script><![CDATA[
                import com.memority.citadel.shared.api.im.operation.ObjectOperationOptions

                def options = new ObjectOperationOptions()
                options.activationModes(["AUTO"])
                MANAGE.newPatch()
                        .set("enabled").value(false)
                        .patch(OBJECT, options)

                return ActionOutcome.success()
                ]]></script>
        </action>
    </actions>
</ctdidm:ObjectPolicy>

Secondary Scope

Propagate attributes between objects
XML
<ctdidm:ObjectPolicy id="manage-instance-sensibility-isSSO-policy"
                     xmlns:ctdidm="http://www.memority.com/citadel/idm/1_0"
                     xmlns:xi="http://www.w3.org/2001/XInclude"
                     xmlns:search="http://www.memority.com/toolkit/search-expression/1_0">
    <name>manage-instance-sensibility-isSSO-policy</name>
    <description/>
    <activation>EVENT</activation>
    <pageSize>10</pageSize>
    <active>true</active>
    <handleEvent>
        <script><![CDATA[
return OPERATION.operation == ObjectOperation.PATCH && (CHANGES.hasAttributeChanged("applicationSensibility") || CHANGES.hasAttributeChanged("applicationIsSSO"))
     ]]></script>
    </handleEvent>
    <scope type="EXPRESSION" objectKind="RESOURCE">
        <searchExpression>
            <search:And />
        </searchExpression>
        <objectTypes>
          <objectType>application</objectType>
        </objectTypes>
    </scope>
    <actions />
    <handleSecondaryScope>
        <script><![CDATA[
return OPERATION.operation == ObjectOperation.PATCH && (CHANGES.hasAttributeChanged("applicationSensibility") || CHANGES.hasAttributeChanged("applicationIsSSO"))
     ]]></script>
    </handleSecondaryScope>
    <secondaryScope type="EXPRESSION" objectKind="RESOURCE">
        <objectTypes>
            <objectType>instance</objectType>
        </objectTypes>
        <searchExpression>
            <search:Prop op="EQUALS" name="instanceApplication">
                <value script="true">OBJECT.id</value>
            </search:Prop>
        </searchExpression>
    </secondaryScope>
    <secondaryActions>
        <action>
           <script><![CDATA[
import com.memority.toolkit.rule.api.ActionOutcome

MANAGE.newPatch()
        .set("instanceSensibility").value(PRIMARY_OPERATION.object.applicationSensibility)
        .set("instanceIsSSO").value(PRIMARY_OPERATION.object.applicationIsSSO)
        .patch(OBJECT)
return ActionOutcome.success()
         ]]></script>
        </action>
    </secondaryActions>
</ctdidm:ObjectPolicy>

Leveraging Reporting Data

It is possible to condition the execution of action on the existence (or non existence) of Reporting Documents correlated to an Object. To use Reporting Correlation, specify the reportingScope property (resp. secondaryReportingScope) along with the Policy Scope (resp. secondaryPolicyScope).

Correlated Reporting Object

A Reporting Document R is deemed correlated to a Managed Object O if and only if:

  • It is from the right Reporting Object Configuration (the Reporting Scope’s reportingObjectConfigurationId property)

  • It matches the Scope (the Reporting Scope’s scope property)

  • It shares an attribute value with the Managed Object (the Reporting Scope’s reportingCorrelationAttribute and imCorrelationAttribute properties). In other words, R.<reportingCorrelationAttribute> == O.<imCorrelationAttribute> .

Positive Vs Negative correlation

When correlationMode=POSITIVE, a managed object will be processed if and only if it matches the Policy Scope and a correlated Reporting Document exists. When correlationMode=NEGATIVE, a managed object will be processed if and only if it matches the Policy Scope and a correlated Reporting Document does not exists.

A typical use case of Negative Correlation is to deactivate identities that did not authenticate in the last 6 months.

Secondary Scope and Actions

For each Managed Object processed by an Object Policy, be it in EVENT or SCHEDULED mode, it is possible to also execute actions on secondary objects, by defining a Secondary Scope and Secondary Actions.

A typical use case is to perform actions on Identities whose security organization is below an organization being patched.

The secondary scope and reporting scope have the exact same semantics as primary scopes, with the difference that they are dynamic, and are resolved for each primary object. The algorithm is as follow:

CODE
for each object O in primaryScope {
  shouldProcess = checkCorrelationWithReportingScope(O, primaryReportingScope)
  if (shouldProcess) {
    evaluatePrimaryActions(O)
    
    if(handleSecondaryScope(O)) {
      secondaryScope = resolveSecondaryScope(O)
      secondaryReportingScope = resolveSecondaryReportingScope(O)
      for each object O2 in secondaryScope {
        shouldProcessSecondaryObject = checkCorrelationWithReportingScope(O2, secondaryReportingScope)
        if (shouldProcessSecondaryObject) {
          evaluateSecondaryActions(O, O2)
        }
      }
    }
  }
}

The PRIMARY_OPERATION context

To allow referencing the Primary Object a PRIMARY_OPERATION context is available to Secondary Actions. It has the same content as the OPERATION context available to Primary Actions

  • PRIMARY_OPERATION.object: the Primary Object

  • PRIMARY_OPERATION.originalObject: the original Primary Object (non null only in EVENT mode)

  • PRIMARY_OPERATION.operation: the operation being performed on the Primary Object (non null only in EVENT mode)

Read next

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.