Approval Steps
Approval is one of the most common actions that a workflow process performs. The IdentityIQ Approval model is constructed to simplify the process of defining an approval structure. Approvals are a special type of step that contain an <Approval> element, specifying how the approval work item is presented for approval.
Some approval steps are designed to get a user's approval on a requested change, as the name implies. However, the approval element can be used any time data needs to be gathered from a user.
Typically, when you use approval steps to gather non-approval data, you use a custom form to:
-
Present the work item to the user
and -
Request the needed information from the user.
For information on creating approval steps, see the section above. Through the XML, the custom form is manually defined within an approval step. You can also specify custom forms for traditional approvals when you need to present the information differently than the standard approval forms layout. SeeWorkflow Forms for more details on usage of custom forms.
Similar to other Workflow elements, you specify some modifiers as attributes on the approval element and specify other modifiers through nested elements within the approval.

Approval |
Purpose |
mode |
Specifies how an approval is processed. Mode can be determined from string, script, rule, call, or reference String is the default. The user interface only supports the selection of a string of one of the values listed below. The XML also enables reference to a process variable containing one of those values or the specification of a script, rule, or method call that can determine one of those values programmatically. Valid values are:
|
owner |
One or more approvers can be specified by string, script, rule, call, or reference. String is the default. The mode determines how and when the item is submitted to each listed owner when more than one is specified. |
renderer |
JSF include to render the work item details. |
return |
Comma-separated values (CSV) list of variable names to copy from completed work items back into workflow. |
send |
CSV list of variable names to include in the work items. |
description |
Defines work item description. For nested approvals, child approvals use the work item defined by the parent approval unless the child approval defines its own work item. You can set the description by string, script, rule, call, or reference String is the default. |
validation |
Used to validate any information the user entered during the approval. This attribute can be specified as string, script, rule, call, or reference. Script is the default. You generally use a nested validationScript element instead of a validation argument. |
Nested Tag within Approval Element |
|
AfterScript |
Provides instructions for additional processing to be done on the item after the approval is complete, and only if approved. Often uses methods in the Approval Rule Library and LCM Workflow Rule Library. If those methods are to be used, the rule libraries must be explicitly included in the workflow using the <RuleLibraries> element. ParallelPoll and serialPoll items always execute this script after all responses are collected. With either of these modes, the logic in this script should aggregate the results and determine if the item should be approved or rejected. The business determines the criteria for approval or rejection, for example majority rule, any approval=approval, etc. In either poll mode, the AfterScript is inherited by child approvals if one is not specified.In other modes, child approvals do not inherit the after script. |
InterceptorScript |
This script is more complex than the AfterScript and is used less often. The script is called in several places in the approval processing: at the approval start, pre-Assimilation, post-Assimilation, when the work item is archived, and at the end of the approval. The stage of the processing is passed to the script as an argument called method that can be used to determine what the script should do at that time. The workflow context's args are also passed to the script. Method values for conditional analysis within InterceptorScript logic:
If an InterceptorScript and AfterScript exist, the InterceptorScript postAssimilation logic launches before the AfterScript. |
validationScript |
Script to perform validation on the work item. For example, you can use this script to validate any data the user enters on the approval before the data is assimilated. This script is inherited by any child approvals. |
Source |
Nested within the AfterScript, InterceptorScript, and validationScript tags and contains the java BeanShell source for the script. |
Arg |
Arguments available to the approval action. Specified by string, script, rule, call, or reference. Most variables are passed to approval through send list. However, args that require any transformation must be sent through an Arg element. Additionally, the following args defined with reserved system names are passed through the Arg element with that name specified:
|
Return |
Return value defines how things should be assimilated from a work item back into the workflow case. This attribute is an alternative to the return attribute CSV of variables. It is more complex and also more powerful. This attribute is rarely used in approvals. It is most often used when returning an approval work item variable to a workflow variable of a different name or when you need to transform the variable contents of a work item with a script. The use of these types of return elements follows the same rules as step returns from steps that subprocesses, with addition of local attribute options. See Step Elements. |
The following basic approval step example presents an account change to the identity's manager for approval. The AfterScript records the approval decision and creates an audit record.
<RuleLibraries>
<Reference class="sailpoint.object.Rule" name="Approval Library"/>
<Reference class="sailpoint.object.Rule" name="LCM Workflow Library"/>
</RuleLibraries>
<Step icon="Approval" name="Manager Approval">
<Approval mode="serial" owner="script:getManagerName(identityName, launcher, fallbackApprover);" renderer="lcmWorkItemRenderer.xhtml" send="approvalSet,identityDisplayName,identityName,policyViolations">
<Arg name="workItemDescription" value="Manager Approval - Account Changes for User: $(identityDisplayName)"/>
<Arg name="workItemNotificationTemplate" value="ref:managerEmailTemplate"/>
<Arg name="workItemRequester" value="$(launcher)"/>
<AfterScript>
<Source>
import sailpoint.workflow.IdentityRequestLibrary;
assimilateWorkItemApprovalSet(wfcontext, item, approvalSet);
IdentityRequestLibrary.assimilateWorkItemApprovalSetToIdentityRequest(wfcontext, approvalSet);
auditDecisions(item);
</Source>
</AfterScript>
</Approval>
<Description>
If approvalScheme contains manager, send an approval for all
requested items in the request. This approval will get the entire
approvalSet as part of the workitem.
</Description>
<Transition to="Build Owner ApprovalSet"
when="script:isApprovalEnabled(approvalScheme, "owner")"/>
<Transition to="Build Security Officer ApprovalSet"
when="script:isApprovalEnabled(approvalScheme, "securityOfficer")"/>
<Transition to="end"/>
</Step>
Note: In the AfterScript in this example, the methods not qualified by the library name are in the LCM Workflow Rule Library that is available to the workflow through the <RuleLibraries> declaration.
The assimilateWorkItemApprovalSetToIdentityRequest method is part of the IdentityRequestLibrary, this is available to the script through the import of that library in the script.
Library methods called through step action attributes are available through the workflow libraries attribute list,. However, when the library methods are executed from within scripts, the library must be specifically imported for the script.

Child approvals created through the user interface are expressed as nested approval elements in the XML. When nested approvals exist, the parent ceases to be an approval of its own. In those case, the sole purpose of the parent approval is to organize and contain the child approvals. The mode on the parent determines how to process the set of peer child approvals.
<Approval mode="string:parallel" name="Approve Region" owner="ref:regionApprover"
send="identityName,region">
<Arg name="workItemDescription" value="string:Approve Region for $(identityName)"/>
<Approval name="childApproval1" owner="string:Walter.Henderson"
send="identityName,region"/>
<Approval name="childApproval2" owner="string:Alan.Bradley"
send="identityName,region"/>
</Approval>
In the example above, childApproval1 and childApproval2 are processed in parallel. Because both of these child approvals are identical (no custom work item config and no children of their own), the same objective can be accomplished with a single approval with multiple owners:
<Approval mode="string:parallel" name="Approve Region" owner="ref:regionApprover"
send="identityName,region">
<Arg name="workItemDescription" value="string:Approve Region for $(identityName)"/>
<Approval name="childApproval1" owner="string:Walter.Henderson"
send="identityName,region"/>
<Approval name="childApproval2" owner="string:Alan.Bradley"
send="identityName,region"/>
</Approval>
Nested approvals can be used effectively when different approval levels are implemented with custom configurations and specifications. For example, the workItemConfig for each of the child approvals can be different, which can result in a notification scheme, escalation policy, etc. for the different approvers.
Nested approvals can be governed by a different approval mode from the one used on the master set and/or can contain their own child approval levels. One child approval can be done as an any approval, one that accepts the ruling of the first responder of several listed approvers, while the highest approval level is managed serially. Another child approval can implement custom workItemConfigs for its own child approvals. The example below illustrates all of these concepts.
Nested approvals can be used effectively when different approval levels are implemented with custom configurations and specifications. For example, the workItemConfig for each of the child approvals can be. The following example that illustrates all of these concepts.
<!-- Approval submitted to HR and to supervisor and manager in serial manner -->
<Approval mode="string:serial" name="Approve Region" owner="spadmin"
send="identityName,region">
<Arg name="workItemDescription" value="string:Approve Region for $(identityName)"/>
<!-- HR Personnel approve region (whoever responds first makes decision) -->
<Approval name="HRApproval" mode="string:any"
owner="ref:HRApprovers" send="identityName,region"/>
<!-- Supervisor and Manager approve region serially after HR approves -->
<!-- Each has a different email template (work item config) for notification -->
<Approval mode="string:serial" name="SupMgrApproval" send="identityName,region">
<Approval name="Supervisor" send="identityName,region" owner="Tom.Jones">
<WorkItemConfig escalationStyle="none">
<NotificationEmailTemplateRef>
<Reference class="sailpoint.object.EmailTemplate"
name="SupervisorApprovalEmail"/>
</NotificationEmailTemplateRef>
</WorkItemConfig>
</Approval>
<Approval name="Manager" send="identityName,region" owner="Mary.Peterson">
<WorkItemConfig escalationStyle="none">
<NotificationEmailTemplateRef>
<Reference class="sailpoint.object.EmailTemplate"
name="ManagerApprovalEmail"/>
</NotificationEmailTemplateRef>
</WorkItemConfig>
</Approval>
</Approval>
</Approval>
This ability to nest approvals, with options to assign different approval modes and work item configurations to each, enables implementers to create highly customized approval structures to meet the needs of the installation.