IdentityIQ uses approval steps in workflows to manage two different types of interactions with users.
Approval steps for the first of these two interaction types are often rendered through a Form object. In those cases, buttons on the form allow the user to communicate a single decision on the whole form, or on the whole collection of data presented on the form; IdentityIQ’s forms support a Submit /OK choice, an Abort/Terminate choice, and a Suspend/Table-for-later response.
In the Lifecycle Manager (LCM) request functions, users commonly enter requests for multiple items which must each be approved individually (in true approval interactions). The single-decision option is inadequate for recording line-item level approvals. In early versions of IdentityIQ, the single-decision-per-approval model was the only one supported. The ApprovalSet object was created to support tracking of distinct decisions within LCM approval requests. All of the out of the box LCM workflows use ApprovalSets and render their approval work items with an XHTML renderer which offers the option of approving and rejecting individual line items.
ApprovalSets are not automatically created for every Approval step. They are explicitly created and managed by various scripts and rules used in the Lifecycle Manager (LCM) workflows. ApprovalSets can be included in an Approval object by adding it during construction (e.g. by an owner rule) or passing it as an argument to the Approval step in the workflow. But there is no built-in logic in the Approval for doing anything with its approvalSet other than passing it into the work item created to gather user input; the XHTML/JSF renderer and/or workflow code must manage the process of updating and interpreting the approvalSet throughout the process. Customers’ custom workflows can also use ApprovalSets, but those workflows must also be explicitly written to create, update, and apply ApprovalSets.
There are several master workflows in LCM – one per request type – which each invoke a series of subprocess workflows for their core functionality. Small details in the master process exist between the request types, but they generally use the same subprocesses for managing the majority of their functionality, including their logic for dealing with ApprovalSets.
The general process followed by the LCM Workflows for using an approvalSet is this:
NOTE: The reason the provisioningPlan must be modified to reflect approvalSet decisions is that there is often no way to roll up all of the decisions into one single “approved” or “rejected” response for the approval; therefore these workflows cannot rely on the final state of the approval step to drive conditional progression to the next actions in the workflow. By applying the approval decisions to the provisioning plan, the workflow can ensure that the approved actions are processed while the rejected ones are not. This mechanism provides support for a "line item veto" style approval when multiple line items are submitted in one LCM shopping cart.
The master ApprovalSet for each workflow case (running instance of the workflow) is created in the Identity Request Initialize subprocess, which is called at the beginning of each of the LCM workflow processes. Specifically, the ApprovalSet is created in the Build Approval Set step (and sometimes modified in the Rebuild Approval Set step) of that workflow. Those steps use a workflow library method to create the approvalSet based on the items in the provisioning plan which was passed to the LCM workflow. The provisioning plan represents the full request submitted in the LCM cart at checkout.
NOTE: Each line item in the approval set is represented as an ApprovalItem. Approval decisions are actually made and processed at the ApprovalItem level.
Individual approvalSets per work item must be created so each approver is presented only the items they need to approve. For most approval types (manager, security officer, list of identities), the approver needs to approve everything in the request, but in an owner approval, the owners of the requested items may be not all be the same person, so each owner only needs to approve the items in the request owned by them. Additionally, in all cases, the approval decisions made by each approver need to be recorded and reported back to the workflow.
The LCM Workflows build their approvals by calling the Provisioning Approval Subprocess workflow. This workflow in turn relies on a workflow library method to create the approvals; the method passes the appropriate approvalSet into each approval and therefore to each approval work item.
The JSF renderer for LCM approvals is lcmWorkItemRenderer.xhtml. That renderer calls a javascript method which updates the work item’s approvalSet with the user’s decisions.
The after script for the approval in Provisioning Approval Subprocess calls a rule library method (in the LCM Workflow Library rule library) called assimilateWorkItemApprovalSet. This script is called when each approval is completed. The assimilateWorkItemApprovalSet method updates the master approvalSet for the workflowcase with the decisions made in the approval work item; it also records any completion comments entered by the approver into the master approvalSet.
NOTE: The default assimilation process assumes that a rejection by any approver should result in rejection of the requested item, so rejection responses from any approver get treated preferentially and will not be overridden by approval responses by other users. Customers can write their own custom assimilation logic if they prefer to apply a different reconciliation method, such as majority rule.
The final use of the ApprovalSet in the LCM workflows is removing any rejected items from the provisioning plan so they will not be provisioned. This process examines the decisions made in the master approvalSet for the workflow and removes from the provisioning plan any items which carry a “rejected” decision in that approvalSet. This occurs in the Process Approval Decisions step of the Identity Request Provision subprocess.
There are a few cases where approvals are not necessary:
In the first two of these cases, all items will automatically be presumed to be approved; in the last case, approval decisions which would have been requested from the requester/approver will be pre-entered as approved. Otherwise, items approved by all approvers (marked “Finished” in the master ApprovalSet) are approved, and those marked “Rejected” are rejected and stripped from the provisioning plan. Any items which arrive at this workflow step with no decisions made on them are considered rejected; it is uncommon for items to arrive at this step in the process without decisions made on them and is considered an error condition, so items in this state are automatically rejected and pulled from the provisioning plan.
This auto-reject default process is important to note because some installations may wish to customize their approval process to auto-approve certain items in certain circumstances beyond the built-in requester-is-approver scenario. Simply deleting the approval is insufficient because it can leave the items in an undecided state, which results in rejection; the master approvalSet must also be updated to reflect an approved decision for the item.
Good stuff here. Thank you for creating it.
Is there any other material on this topic and/or code examples for custom approvals?
You may want to search around on Compass for other things people have posted (wiki and forums), but I don't have any specific references to point you to offhand. I suggest you take a look at the details in the two OOTB approval subprocesses (Identity Request Approve and Provisioning Approval Subprocess) -- specifically, look at the after scripts included in them. If you have specific questions about approvals, post them to the Forum so the whole community can try to help (more people follow the forums than the wiki or any specific wiki article, so your questions will have a broader audience and are more likely to be helpfully answered there).
Thank you for sharing this detailed information.
I am working on access request and wanted to see if we have only Approve All/Reject All option instead or individual Approve/Reject option.
Is there a way, we can hide/disable individual approve/reject option and just keep Approve All/Reject All ?
@Arpit_Patel @jennifer_mitchell
Did you find the solution for
"Is there a way, we can hide/disable individual approve/reject option and just keep Approve All/Reject All ?"
The is a great article to drive in-depth into the build approval set and approval process in the LCM workflows, thanks for posting.
@jennifer_mitchell& @darylclaude_medinamedina, thank you for this detailed content that provides a great deal of clarity on the approval engine of IIQ.
As you mentioned under the sub-topic " Creating approver-specific approval sets", I needed a bit of clarity on how to set the approver types into the approval set explicitly as I currently am leveraging an approval assignment rule to treat approvals differently for 100+ applications. However, only Identity Approvals are getting generated because of which all the approval items are sent to the same approver at level 2 and level 3 in a request where I have 2 or more entitlements clubbed in my access request.
Here I would want the approver type "owner" for level 2 and level 3.
I have all the handers in my code in setting the appropriate owner iterating through the items in the access request but would like to know that one piece of logic in setting the approver type explicitly in an approval assignment rule.