Customizing the LCM Provisioning - Request Access Workflow

Which IIQ version are you inquiring about?

8.3

Share all details about your problem, including any error messages you may have received.

To start, we have a complex structure being a University & Health Care organization. We have multiple authoritative sources for person data where an individual may be listed in these sources. (Student & Employee at the same time, for example) Working with our implementation partner, they developed a form when submitting an access request that allows the submitter to choose the correct manager that the request should go to for approval (Student & Employee and request is submitted to grant the student persona access for something, ensure that persona’s manager is the one that approves it.). Now the issue comes up when a requestor is submitting a request for multiple users for the same access and they have multiple personas. When the workflow tries to resolve this, it currently ends with an error, but the forms to fill out to select the correct persona are in their work items. (But they are not aware of it, they can find them and fill those out and the request will move on as expected)

We are looking for assistance on possible options:

  1. Trying to figure out a way to have the workflow loop correctly through each persona selection forms at the time of request submittal.
  2. If 1 is not possible, instead of an error message, give a more detailed message on the next steps the requestor needs to take to get their request completed.

Thanks,

-Rik

I have included the workflow/business process here:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Workflow PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Workflow configForm="Provisioning Workflow Config Form" created="1679519229735" explicitTransitions="true" handler="sailpoint.api.StandardWorkflowHandler" id="0a56490d8705153281870b25a7270b87" libraries="Identity,Role,PolicyViolation,LCM,BatchRequest" modified="1725396535187" name="OHSU - LCM Provisioning - Request Access" taskType="LCM" type="LCMProvisioning">
  <Variable input="true" name="identityName">
    <Description>The name of the identity being updated.</Description>
  </Variable>
  <Variable initializer="false" input="true" name="endOnManualWorkItems">
    <Description>Option to skip requests with manual work items.</Description>
  </Variable>
  <Variable initializer="false" input="true" name="endOnProvisioningForms">
    <Description>Option to skip requests with provisioning forms.</Description>
  </Variable>
  <Variable initializer="script:(identityDisplayName != void) ? identityDisplayName : resolveDisplayName(identityName)" input="true" name="identityDisplayName">
    <Description>The displayName of the identity being updated. Query for this using a projection query and fall back to the name.</Description>
  </Variable>
  <Variable input="true" name="plan">
    <Description>The provisioning plan ready to execute.</Description>
  </Variable>
  <Variable input="true" name="flow">
    <Description>The name of the LCM flow that launched this workflow. This is one of these three values: AccountsRequest EntitlementsRequest RolesRequest AttributeSync</Description>
  </Variable>
  <Variable editable="true" initializer="false" name="optimisticProvisioning">
    <Description>Set to true to enable optimistic provisioning. This will cause changes to the entitlements compiled from role assignments to be applied immediately to the identity cube rather than waiting for the next refresh/reaggregation after the provisioning system completes the request.</Description>
  </Variable>
  <Variable editable="true" initializer="true" name="foregroundProvisioning">
    <Description>Normally provisioning is done in a step that uses the &amp;quot;background&amp;quot; option to force the workflow to be suspend and be resumed in a background task thread. This prevents the browser session from hanging since provision can sometimes take a long time. For demos and testing it can be better to do this in the foreground so that provisioning will have been performed when control is returned to the user. This prevents having to run the Perform Maintenance task to see the results of the request.</Description>
  </Variable>
  <Variable input="true" name="batchRequestItemId">
    <Description>Used by the batch interface to record back individual request item status. The specific item id for the individual request in the batch file.</Description>
  </Variable>
  <Variable editable="true" initializer="true" name="doRefresh">
    <Description>Set to true to cause an identity refresh after the changes in the plan have been provisioned. This is normally off, you might want this on if you want modification of identity or link attributes to result in an immediate re-evaluation of assigned and detected roles.</Description>
  </Variable>
  <Variable initializer="user, requester" input="true" name="notificationScheme">
    <Description>A string that specifies who should be notified when the request has been complete. The value can be null or a csv of one or more of the following options. none or null disable notifications user Identity that is being update will be notified. manager The manager of the Identity that is being updated will be notified. requester The person that has requested the update will be notified.</Description>
  </Variable>
  <Variable initializer="OHSU_LCMUserNotification" input="true" name="userEmailTemplate">
    <Description>The email template to use for user notification.</Description>
  </Variable>
  <Variable initializer="OHSU_LCMRequesterNotification" input="true" name="requesterEmailTemplate">
    <Description>The email template to use for requester notification.</Description>
  </Variable>
  <Variable initializer="OHSU_LCMManagerNotification" input="true" name="managerEmailTemplate">
    <Description>The email template to use for manager notification.</Description>
  </Variable>
  <Variable input="true" name="securityOfficerEmailTemplate">
    <Description>The email template to use for security officer notification.</Description>
  </Variable>
  <Variable initializer="parallelPoll" input="true" name="approvalMode">
    <Description>A string that specifies how we should handle the approvals. By default this is serial since most of these request with the exception of manager transfers will have only one approver. parallel Approvals are processed concurrently and there must be consensus, we wait for all approvers to approve. The first approver that rejects terminates the entire approval. parallelPoll Approvals are processed concurrently but consensus is not required. All approvals will be processed, we don&amp;#39;t stop if there are any rejections. serial Approvals are processed one at a time and there must be consensus. The first approver that rejects terminates the entire approval. serialPoll Approvals are processed in order but consensus is not required. All approvals will be processed, we don&amp;#39;t stop if there are any rejections. In effect we are &amp;quot;taking a poll&amp;quot; of the approvers. any Approvals are processed concurrently, the first approver to respond makes the decision
      for the group.</Description>
  </Variable>
  <Variable initializer="manager, owner" input="true" name="approvalScheme">
    <Description>A csv string that specifies how approval items should be generated for the incoming request. The value can be &amp;quot;none&amp;quot;, in which case approvals are disabled. The value can also be a combination of any of the values below in any order, separated by commas. The order in which they are specified is the order in which they are processed: owner The object owner gets the approval item. For Role approvals this is the Role object owner. For Entitlement approvals this is the Entitlement object owner. manager The manager gets the approval item. securityOfficer The identity in the variable securityOfficerName gets the approval item. identity The identities/workgroups in the variable approvingIdentities get the approval item.</Description>
  </Variable>
  <Variable initializer="OHSU_LCMIdentityUpdateApproval" input="true" name="approvalEmailTemplate">
    <Description>The email template to use for approval notifications.</Description>
  </Variable>
  <Variable initializer="Normal" input="true" name="workItemPriority">
    <Description>The String version of a WorkItem.Priority. This variable is used to set the priority on all of the workitems generated as part of this workflow and also set on the IdentityRequest object.</Description>
  </Variable>
  <Variable input="true" name="securityOfficerName">
    <Description>The name of the identity that will be sent approvals during security officer approvals.</Description>
  </Variable>
  <Variable initializer="DIA Team" input="true" name="fallbackApprover">
    <Description>A String that specifies the name of the Identity that will be assigned any approvals where the owner of the approver can&amp;#39;t be resolved. Example if the scheme is &amp;quot;owner&amp;quot; and the application doesn&amp;#39;t specify and owner.</Description>
  </Variable>
  <Variable initializer="continue" input="true" name="policyScheme">
    <Description>A String that specifies how policy checks effect the overall process. none - disabled policy checking continue - continue if policy violations are found interactive - allow requester to remove request items which are causing violations fail - this option will cause the workflow to terminate immediately if any policy violations are found. Note that the requester will not be notified that the workflow has terminated.</Description>
  </Variable>
  <Variable initializer="false" input="true" name="enableRetryRequest">
    <Description>When set to true it will disable the workflow retry loop and let the Provision step launch requests to handle the retries. Enabling this flag will enable some older functionality.</Description>
  </Variable>
  <Variable input="true" name="policiesToCheck">
    <Description>A List of policies that should be checked. If this list is empty all violations will be checked. Used in combination with policyScheme.</Description>
  </Variable>
  <Variable initializer="LCM" input="true" name="source">
    <Description>String version of sailpoint.object.Source to indicate where the request originated. Defaults to LCM.</Description>
  </Variable>
  <Variable initializer="false" name="trace">
    <Description>Used for debugging this workflow and when set to true trace will be sent to stdout.</Description>
  </Variable>
  <Variable name="approvalSet">
    <Description>This attributes is set during the &amp;quot;Build Approval Set&amp;quot; step, which builds this list by going through the ProvisioningPlan to build the line items that need to be approved, This variable includes all ApprovalItems that are part of the request process and is updated during the AfterScript of the approval process by assimilating the decisions and comments from the Approvals copy of the ApprovalItem.</Description>
  </Variable>
  <Variable initializer="true" name="allowRequestsWithViolations">
    <Description>If this variable is set to true, requesters will be able to proceed past the Policy Violation Review form without taking any action on policy violations resulting from the request. This is only relevant if policyScheme=interactive.</Description>
  </Variable>
  <Variable initializer="true" name="requireViolationReviewComments">
    <Description>If true, requesters will be required to enter in comments if they proceed with a request that will result in policy violations. This is only relevant if policyScheme=interactive.</Description>
  </Variable>
  <Variable name="project">
    <Description>ProvisioningProject which is just a compiled version of the ProvisioningPlan.</Description>
  </Variable>
  <Variable name="policyViolations">
    <Description>List of policy violations that were found during our initial policy scan. This list is passed into each work item so the approvers can see pending violations.</Description>
  </Variable>
  <Variable name="identityRequestId" output="true">
    <Description>The sequence id of the Identity request object which is stored in the name field of the identity request and auto-incremented.</Description>
  </Variable>
  <Variable name="violationReviewDecision">
    <Description>Decision made by the user in the Policy Violation Review step. This may be one of three choices: -ignore: User is ignoring the violations and letting the request continue. If requireViolationReviewComments=true the user will be required to enter comments indicating why they are allowing the violations. -remediate: Indicates that the user removed the request items that were causing the violations -cancel: Indicates that the user decided to abandon the request, terminating the workflow.</Description>
  </Variable>
  <Variable name="workItemComments">
    <Description>Global comments accumulated during the workflow which should be shared with other approvals. When a new approval is created, the comments in this list will be added to the work item.</Description>
  </Variable>
  <Variable input="true" name="ticketManagementApplication">
    <Description>Name of the application that can handle ticket requests. When non-null the Manage Ticket Steps will be visited to open tickets during the workflow lifecycle.</Description>
  </Variable>
  <Variable name="ticketId">
    <Description>The id of the ticket that is generated by the ticketingManagementApplication. This is typically generated on the &amp;quot;open&amp;quot; call, and then used in subsequent calls. It is also stored on the IdentityRequest object under the externalTicketId variable.</Description>
  </Variable>
  <Variable input="true" name="managerElectronicSignature">
    <Description>The name of the electronic signature object that should be used when workitems are completed by a manager.</Description>
  </Variable>
  <Variable input="true" name="ownerElectronicSignature">
    <Description>The name of the electronic signature object that should be used when workitems are completed by object owners.</Description>
  </Variable>
  <Variable input="true" name="securityOfficerElectronicSignature">
    <Description>The name of the electronic signature object that should be used when workitems are completed by the security officer.</Description>
  </Variable>
  <Variable input="true" name="approvingIdentities">
    <Description>List of identities and/or workgroups names/ids that should be involved in the approval process.</Description>
  </Variable>
  <Variable input="true" name="identityElectronicSignature">
    <Description>The name of the electronic signature object that should be used when workitems are completed by identities and/or workgroups.</Description>
  </Variable>
  <Variable input="true" name="identityEmailTemplate">
    <Description>Name of the email template to use when notifying the identities/workgroups of pending approvals.</Description>
  </Variable>
  <Variable initializer="true" input="true" name="filterRejects">
    <Description>True to filter rejected items when running in Serial/SerialPoll mode.</Description>
  </Variable>
  <Variable initializer="false" input="true" name="setPreviousApprovalDecisions">
    <Description>True to pre-populate approval decisions from previous approvals.</Description>
  </Variable>
  <Variable initializer="owner" input="true" name="approvalSplitPoint">
    <Description>Variable to determine when to split into parallel processing. This should map to a configured approvalScheme. We will process all schemes up until the approvalSplitPoint in the Pre Split approvals, and the remaining schemes after we split the items. If this is not specified, we will not split the Provisioning project, and process the entire project as a whole.</Description>
  </Variable>
  <Variable name="splitPlans">
    <Description>List of ProvisioningPlan that is generated from the splitPlans step if approvalSplitPoint is set.</Description>
  </Variable>
  <Variable name="splitProjects">
    <Description>Variable to store the returns if approvalSplitPoint is set. This will contain a List&amp;lt;ProvisioningProject&amp;gt;</Description>
  </Variable>
  <Variable name="splitApprovalSet">
    <Description>Variable to store the list of approvalSets returned from the split subprocess if approvalSplitPoint is set.</Description>
  </Variable>
  <Variable name="splitWorkItemComments">
    <Description>Variable to store the list of WorkItem comments returned from the split subprocess if approvalSplitPoint is set.</Description>
  </Variable>
  <Variable initializer="false" input="true" name="saveUnmanagedPlan_WithProjectArgument">
    <Description>When true we will pass the project in to save unmanaged plan as an argument.</Description>
  </Variable>
  <Variable initializer="false" input="true" name="requireCommentsForApproval">
    <Description>When true we will require comments when an approval item is approved.</Description>
  </Variable>
  <Variable initializer="false" input="true" name="requireCommentsForDenial">
    <Description>When true we will require comments when an approval item is denied.</Description>
  </Variable>
  <Variable initializer="OHSU - ApprovalAssignment - Request Access" name="approvalAssignmentRule">
    <Description>Approval assignment rule used to manipulate originally generated approvals.</Description>
  </Variable>
  <Variable initializer="OHSU - ApprovalAssignment - Manager - Request Access" name="managerApprovalAssignmentRule">
    <Description>Approval assignment rule used to manipulate originally generated approvals.</Description>
  </Variable>
  <Variable initializer="OHSU - ApprovalAssignment - Owner - Request Access" name="ownerApprovalAssignmentRule">
    <Description>Approval assignment rule used to manipulate originally generated approvals.</Description>
  </Variable>
  <Variable initializer="true" name="clearApprovalDecisions">
    <Description>Variable to clear approval decisions from next approval.</Description>
  </Variable>
  <Variable initializer="true" name="noTriggers">
    <Description>Variable to disable triggers during access request</Description>
  </Variable>
  <Variable initializer="24" name="workItemHoursBetweenReminders">
    <Description>The number of hours to wait between sending reminders to approvers.</Description>
  </Variable>
  <Variable initializer="24" name="workItemHoursTillEscalation">
    <Description>The number of hours to wait until an approval should be escalated.</Description>
  </Variable>
  <Variable initializer="OHSU_AccessRequestReminder" name="workItemReminderTemplate">
    <Description>The email template that should be used when sending out reminders.</Description>
  </Variable>
  <Variable initializer="Request Access - Escalation" name="workItemEscalationRule">
    <Description>The rule used to assign a new ownder during escalation.</Description>
  </Variable>
  <Variable initializer="3" name="workItemMaxReminders">
    <Description>The maximum number of reminder emails that will be sent before we begin the escalation process.</Description>
  </Variable>
  <Variable initializer="both" name="workItemEscalationStyle">
    <Description>Escalation style for workitem.</Description>
  </Variable>
  <Variable initializer="true" name="autoVerifyIdentityRequest"/>
  <Variable name="selectedPersona"/>
  <Variable input="true" name="psForm"/>
  <Variable name="mgr"/>
  <Variable name="size"/>
  <RuleLibraries>
    <Reference class="sailpoint.object.Rule" id="0a56490d815b1c0381815bdc6bb80187" name="LCM Workflow Library"/>
  </RuleLibraries>
  <Step icon="Start" name="Start" posX="25" posY="10">
    <Transition to="Check Personas"/>
  </Step>
  <Step icon="Task" name="Check Personas" posX="28" posY="98" resultVariable="selectedPersona">
    <Arg name="identityName" value="ref:identityName"/>
    <Script>
      <Source>
        import java.util.ArrayList;
        import sailpoint.object.Identity;


        List psRoles = new ArrayList();

        Identity ident = context.getObjectByName(Identity.class, identityName);
        //change to global attr mapping source rule
        psRoles = ident.getAttribute("personas");

        if(psRoles.size()==1) {

        String singlePersona = psRoles.get(0);

        return singlePersona;
        }
        return "";

      </Source>
    </Script>
    <Transition to="setPersonaAttr" when="script:!selectedPersona.isEmpty()"/>
    <Transition to="Initialize Form"/>
  </Step>
  <Step icon="Task" name="Initialize Form" posX="19" posY="222" resultVariable="psForm">
    <Transition to="selectPersona"/>
  </Step>
  <Step name="selectPersona" posX="68" posY="349">
    <Approval name="Select User Persona" owner="ref:launcher" return="selectedPersona" send="identityName">
      <Arg name="selectedPersona" value="ref:selectedPersona"/>
      <Arg name="mgr" value="ref:mgr"/>
      <Arg name="identityDisplayName" value="ref:identityDisplayName"/>
      <Arg name="workItemDescription" value="string:Select User Persona for $(identityName)"/>
      <Form name="Select User Persona">
        <Attributes>
          <Map>
            <entry key="pageTitle" value="Select User Persona"/>
          </Map>
        </Attributes>
        <Section name="userInstructions" type="text">
          <Field value="This user has multiple personas within the organization (Example: User is a Student and Employee). Please select the correct persona below to complete this request."/>
          <Field value="Note: Currently all Employees have PO Externals personas. Currently all PO Externals have an Employee personas."/>
        </Section>
        <Section name="User Info" type="text">
          <Field displayName="Identity" name="identityDisplayName"/>
        </Section>
        <Section name="More Info">
          <Field displayName="Please select one." displayType="radio" name="selectedPersona" postBack="true" required="true" type="string">
            <AllowedValuesDefinition>
              <Script>
                <Source>
                  import java.util.ArrayList;
                  import sailpoint.object.Identity;

                  //change to getting links that are active?

                  List psRoles = new ArrayList();

                  Identity ident = context.getObjectByName(Identity.class, identityName);
                  //change to global attr mapping source rule
                  psRoles = ident.getAttribute("personas");
                  return psRoles;
                </Source>
              </Script>
            </AllowedValuesDefinition>
          </Field>
          <Field displayName="Approver" dynamic="true" name="mgr" readOnly="true" type="string">
            <Script>
              <Source>
                import sailpoint.api.IdentityService;
                import sailpoint.object.Application;
                import sailpoint.object.Custom;
                import sailpoint.object.Identity;
                import sailpoint.object.Link;
                import sailpoint.tools.Util;

                Custom custom = context.getObjectByName(Custom.class, "OHSU - Persona Application Mappings");
                IdentityService idService = new IdentityService(context);
                if(selectedPersona == null)
                {
                  return "";
                }

                if(null != custom)
                {
                  String appName = custom.get(selectedPersona);

                  if(null != appName)
                  {
                    List links = idService.getLinks(identity, context.getObjectByName(Application.class, appName));

                    if(Util.size(links) > 0)
                    {
                      Link link = links.get(0);
                      String mgr = "";

                      switch(appName)
                      {
                        case "Ellucian Banner":
                          mgr="ManagerName";
                        break;

                        case "HMC Flatfile": 
                          mgr="Supervisor Name";
                        break;

                        case "Oracle - Employee":
                          mgr="SUPERVISOR_NAME";
                        break;

                        case "Oracle - PO External":
                          mgr="SUPERVISOR_NAME";
                        break;

                        case "Seczetta - NEProfile - Affiliate Staff" :
                          mgr="affstaff_manager";
                        break;

                        case "Seczetta - NEProfile - Contractor" :
                          mgr="contractor_manager";
                        break;

                        case "Seczetta - NEProfile - Emeritus" :
                          mgr="emeritus_manager";
                        break;

                        case "Seczetta - NEProfile - Vendor" :
                          mgr="vendor_manager";
                        break;

                        case "Seczetta - NEProfile - Visiting Researcher" :
                          mgr="visitres_manager";
                        break;

                        case "Seczetta - NEProfile - Visiting Student" :
                          mgr="visitstud_manager";
                        break;

                        case "Seczetta - NEProfile - Volunteer" :
                          mgr="volunteer_manager";
                        break;
                      }

                      if(mgr != null)
                      {
                        String mgrApprover = link.getAttribute(mgr);

                        if(appName.startsWith("Seczetta"))
                        {
                          String[] values = mgrApprover.split("\\|");
                          mgrApprover=values[1];
                        }

                        return mgrApprover;
                      }
                    }
                    return "DIA Team";
                  }
                  return "DIA Team";
                }
                return "No mapping exists for approver";
              </Source>
            </Script>
          </Field>
        </Section>
        <Button action="back" label="Cancel"/>
        <Button action="next" label="Submit"/>
      </Form>
    </Approval>
    <Arg name="selectedPersona" value="ref:selectedPersona"/>
    <Transition to="setPersonaAttr" when="approved"/>
  </Step>
  <Step icon="Task" name="setPersonaAttr" posX="116" posY="157">
    <Arg name="identityName" value="ref:identityName"/>
    <Arg name="selectedPersona" value="ref:selectedPersona"/>
    <Script>
      <Source>
        import sailpoint.object.Identity;
        
        Identity id = context.getObjectByName(Identity.class, identityName);
        
        if(selectedPersona.contains("Contractor") || selectedPersona.contains("Emeritus") || selectedPersona.contains("Visiting") || selectedPersona.contains("Affiliate") || selectedPersona.contains("Volunteer") || selectedPersona.contains("Vendor") || selectedPersona.contains("PO External")) {

        id.setAttribute("adRequestedPersona", selectedPersona);
        context.saveObject(id);
        context.commitTransaction();

        }
        

      </Source>
    </Script>
    <Transition to="Initialize"/>
  </Step>
  <Step icon="Task" name="Initialize" posX="134" posY="10">
    <Arg name="formTemplate" value="Identity Update"/>
    <Arg name="identityName" value="ref:identityName"/>
    <Arg name="enableRetryRequest" value="ref:enableRetryRequest"/>
    <Arg name="allowRequestsWithViolations" value="ref:allowRequestsWithViolations"/>
    <Arg name="endOnManualWorkItems" value="ref:endOnManualWorkItems"/>
    <Arg name="policiesToCheck" value="ref:policiesToCheck"/>
    <Arg name="workItemPriority" value="ref:workItemPriority"/>
    <Arg name="source" value="ref:source"/>
    <Arg name="policyScheme" value="ref:policyScheme"/>
    <Arg name="identityDisplayName" value="ref:identityDisplayName"/>
    <Arg name="requireViolationReviewComments" value="ref:requireViolationReviewComments"/>
    <Arg name="identityRequest"/>
    <Arg name="trace" value="ref:trace"/>
    <Arg name="batchRequestItemId" value="ref:batchRequestItemId"/>
    <Arg name="enableApprovalRecommendations"/>
    <Arg name="asyncCacheRefresh"/>
    <Arg name="endOnProvisioningForms" value="ref:endOnProvisioningForms"/>
    <Arg name="optimisticProvisioning" value="ref:optimisticProvisioning"/>
    <Arg name="plan" value="ref:plan"/>
    <Arg name="flow" value="ref:flow"/>
    <Arg name="launcher" value="ref:launcher"/>
    <Description> Call the standard subprocess to initialize the request, this includes auditing, building the approvalset, compiling the plan into project and checking policy violations. 
    </Description>
    <Return name="project" to="project"/>
    <Return name="approvalSet" to="approvalSet"/>
    <Return name="policyViolations" to="policyViolations"/>
    <Return name="identityRequestId" to="identityRequestId"/>
    <Return name="violationReviewDecision" to="violationReviewDecision"/>
    <Return merge="true" name="workItemComments" to="workItemComments"/>
    <WorkflowRef>
      <Reference class="sailpoint.object.Workflow" id="0a56490d815b1c0381815bdce39602ee" name="Identity Request Initialize"/>
    </WorkflowRef>
    <Transition to="Exit On Manual Work Items" when="script:(isTrue(endOnManualWorkItems) &amp;&amp; (project.getUnmanagedPlan() != null))"/>
    <Transition to="Exit On Provisioning Form" when="script:(isTrue(endOnProvisioningForms) &amp;&amp; (project.hasQuestions()))"/>
    <Transition to="Exit On Policy Violation">
      <Script>
        <Source>("cancel".equals(violationReviewDecision) || ((size(policyViolations) > 0 ) &amp;&amp; (policyScheme.equals("fail"))))</Source>
      </Script>
    </Transition>
    <Transition to="Create Ticket"/>
  </Step>
  <Step condition="script:(ticketManagementApplication != null)" icon="Task" name="Create Ticket" posX="381" posY="6">
    <Arg name="trace" value="ref:trace"/>
    <Arg name="ticketManagementApplication" value="ref:ticketManagementApplication"/>
    <Arg name="project" value="ref:project"/>
    <Arg name="action" value="open"/>
    <Arg name="workItemPriority" value="ref:workItemPriority"/>
    <Arg name="identityRequestId" value="ref:identityRequestId"/>
    <Arg name="source" value="ref:source"/>
    <Arg name="ticketProject"/>
    <Arg name="ticketId" value="ref:ticketId"/>
    <Arg name="ticketDataGenerationRule"/>
    <Arg name="ticketPlan"/>
    <Description> Call a subprocess to create a ticket in the ticketManagementApplication is non-null. You can specify a specific 'ticketDataGenerationRule' here or you can also specify it on the application. It'll be read from the argument first and fall back to the ' application config. 
    </Description>
    <Return name="ticketId" to="externalTicketId"/>
    <WorkflowRef>
      <Reference class="sailpoint.object.Workflow" id="0a56490d815b1c0381815bdc6b1f017b" name="Manage Ticket"/>
    </WorkflowRef>
    <Transition to="Pre Split Approve" when="script:(!isNull(approvalSplitPoint) &amp;&amp; csvToList(approvalScheme).contains(approvalSplitPoint))"/>
    <Transition to="Approve and Provision"/>
  </Step>
  <Step condition="script:((flow == null) ||  (!&quot;UnlockAccount&quot;.equals(flow)))" icon="Task" name="Pre Split Approve" posX="518" posY="63">
    <Arg name="approvalScheme">
      <Script>
        <Source>
          import java.util.List;
          import java.util.ArrayList;
          import java.util.Iterator;
          import sailpoint.tools.Util;

          List schemes = Util.csvToList(approvalScheme);
          List preSchemes = new ArrayList&lt;String>();
          for (String s : Util.safeIterable(schemes)) {
          if (s.equals(approvalSplitPoint)) {
          break;
          } else {
          preSchemes.add(s);
          }
          }
          return Util.listToCsv(preSchemes);
        </Source>
      </Script>
    </Arg>
    <Arg name="identityEmailTemplate" value="ref:identityEmailTemplate"/>
    <Arg name="securityOfficerElectronicSignature" value="ref:securityOfficerElectronicSignature"/>
    <Arg name="fallbackApprover" value="ref:fallbackApprover"/>
    <Arg name="workItemHoursBetweenReminders"/>
    <Arg name="workItemPriority" value="ref:workItemPriority"/>
    <Arg name="project" value="ref:project"/>
    <Arg name="workItemComments"/>
    <Arg name="identityRequestId" value="ref:identityRequestId"/>
    <Arg name="approvalSplitPoint" value="ref:approvalSplitPoint"/>
    <Arg name="managerElectronicSignature" value="ref:managerElectronicSignature"/>
    <Arg name="workItemDescription"/>
    <Arg name="identityDisplayName" value="ref:identityDisplayName"/>
    <Arg name="ownerElectronicSignature" value="ref:ownerElectronicSignature"/>
    <Arg name="approvalMode" value="ref:approvalMode"/>
    <Arg name="trace" value="ref:trace"/>
    <Arg name="dontUpdatePlan"/>
    <Arg name="workItemEscalationRule"/>
    <Arg name="approvalAssignmentRule" value="ref:approvalAssignmentRule"/>
    <Arg name="plan" value="ref:plan"/>
    <Arg name="flow" value="ref:flow"/>
    <Arg name="requireCommentsForApproval" value="ref:requireCommentsForApproval"/>
    <Arg name="ownerApprovalAssignmentRule" value="ref:ownerApprovalAssignmentRule"/>
    <Arg name="identityElectronicSignature" value="ref:identityElectronicSignature"/>
    <Arg name="workItemEscalationStyle"/>
    <Arg name="identityName" value="ref:identityName"/>
    <Arg name="approvalSet" value="ref:approvalSet"/>
    <Arg name="policyViolations" value="ref:policyViolations"/>
    <Arg name="ownerEmailTemplate" value="ref:approvalEmailTemplate"/>
    <Arg name="filterRejects" value="ref:filterRejects"/>
    <Arg name="workItemReminderTemplate"/>
    <Arg name="workItemEscalationTemplate"/>
    <Arg name="setPreviousApprovalDecisions" value="ref:setPreviousApprovalDecisions"/>
    <Arg name="clearApprovalDecisions" value="ref:clearApprovalDecisions"/>
    <Arg name="noTriggers" value="ref:noTriggers"/>
    <Arg name="selectedPersona"/>
    <Arg name="workItemMaxReminders"/>
    <Arg name="requireCommentsForDenial" value="ref:requireCommentsForDenial"/>
    <Arg name="approvalEmailTemplate"/>
    <Arg name="approvingIdentities" value="ref:approvingIdentities"/>
    <Arg name="securityOfficerEmailTemplate" value="ref:approvalEmailTemplate"/>
    <Arg name="securityOfficerName" value="ref:securityOfficerName"/>
    <Arg name="workItemHoursTillEscalation"/>
    <Arg name="managerEmailTemplate" value="ref:approvalEmailTemplate"/>
    <Arg name="managerApprovalAssignmentRule" value="ref:managerApprovalAssignmentRule"/>
    <Arg name="launcher" value="ref:launcher"/>
    <Description> Call to our standard subprocess to handle the default approvals for manager, owner and security officer. 
    </Description>
    <Return name="approvalSet"/>
    <Return name="workItemComments"/>
    <Return name="project"/>
    <WorkflowRef>
      <Reference class="sailpoint.object.Workflow" id="0a56490d8705153281870b2556370b83" name="OHSU - Provisioning Approval Subprocess - Request Access"/>
    </WorkflowRef>
    <Transition to="Split Plan"/>
  </Step>
  <Step action="call:splitProvisioningPlan" icon="Task" name="Split Plan" posX="618" posY="63" resultVariable="splitPlans">
    <Arg name="project" value="ref:project"/>
    <Description> Step to split the provisioning project into individual projects for each item requested. This will only run if the approvalSplitPoint is configured. 
    </Description>
    <Transition to="Approve and Provision Split"/>
  </Step>
  <Step icon="Task" name="Approve and Provision Split" posX="783" posY="63">
    <Arg name="formTemplate" value="Identity Update"/>
    <Arg name="identityEmailTemplate" value="ref:identityEmailTemplate"/>
    <Arg name="enableRetryRequest" value="ref:enableRetryRequest"/>
    <Arg name="securityOfficerElectronicSignature" value="ref:securityOfficerElectronicSignature"/>
    <Arg name="fallbackApprover" value="ref:fallbackApprover"/>
    <Arg name="endOnManualWorkItems" value="ref:endOnManualWorkItems"/>
    <Arg name="userEmailTemplate" value="ref:userEmailTemplate"/>
    <Arg name="project" value="ref:project"/>
    <Arg name="workItemComments" value="ref:workItemComments"/>
    <Arg name="identityRequestId" value="ref:identityRequestId"/>
    <Arg name="approvalSplitPoint" value="ref:approvalSplitPoint"/>
    <Arg name="source" value="ref:source"/>
    <Arg name="identityDisplayName" value="ref:identityDisplayName"/>
    <Arg name="foregroundProvisioning" value="ref:foregroundProvisioning"/>
    <Arg name="ownerElectronicSignature" value="ref:ownerElectronicSignature"/>
    <Arg name="batchRequestItemId" value="ref:batchRequestItemId"/>
    <Arg name="saveUnmanagedPlan_WithProjectArgument" value="ref:saveUnmanagedPlan_WithProjectArgument"/>
    <Arg name="plan" value="ref:plan"/>
    <Arg name="flow" value="ref:flow"/>
    <Arg name="identityElectronicSignature" value="ref:identityElectronicSignature"/>
    <Arg name="identityName" value="ref:identityName"/>
    <Arg name="approvalSet" value="ref:approvalSet"/>
    <Arg name="filterRejects" value="ref:filterRejects"/>
    <Arg name="ownerEmailTemplate" value="ref:approvalEmailTemplate"/>
    <Arg name="splitProvisioning" value="true"/>
    <Arg name="workItemEscalationTemplate" value="ref:workItemEscalationTemplate"/>
    <Arg name="clearApprovalDecisions" value="ref:clearApprovalDecisions"/>
    <Arg name="noTriggers" value="ref:noTriggers"/>
    <Arg name="requireCommentsForDenial" value="ref:requireCommentsForDenial"/>
    <Arg name="workItemMaxReminders" value="ref:workItemMaxReminders"/>
    <Arg name="requesterEmailTemplate" value="ref:requesterEmailTemplate"/>
    <Arg name="approvalEmailTemplate" value="ref:approvalEmailTemplate"/>
    <Arg name="ticketManagementApplication" value="ref:ticketManagementApplication"/>
    <Arg name="securityOfficerName" value="ref:securityOfficerName"/>
    <Arg name="approvingIdentities" value="ref:approvingIdentities"/>
    <Arg name="workItemHoursTillEscalation" value="ref:workItemHoursTillEscalation"/>
    <Arg name="managerEmailTemplate" value="ref:approvalEmailTemplate"/>
    <Arg name="managerApprovalAssignmentRule" value="ref:managerApprovalAssignmentRule"/>
    <Arg name="launcher" value="ref:launcher"/>
    <Arg name="approvalScheme">
      <Script>
        <Source>
          import java.util.List;
          import java.util.Iterator;
          import sailpoint.tools.Util;
          List schemes = Util.csvToList(approvalScheme);
          Iterator it = schemes.iterator();
          while (it.hasNext()) {
          String s = it.next();
          if (!s.equals(approvalSplitPoint)) {
          it.remove();
          } else {
          break;
          }
          }
          return Util.listToCsv(schemes);
        </Source>
      </Script>
    </Arg>
    <Arg name="workItemHoursBetweenReminders" value="ref:workItemHoursBetweenReminders"/>
    <Arg name="workItemPriority" value="ref:workItemPriority"/>
    <Arg name="managerElectronicSignature" value="ref:managerElectronicSignature"/>
    <Arg name="approvalMode" value="ref:approvalMode"/>
    <Arg name="trace" value="ref:trace"/>
    <Arg name="workItemEscalationRule" value="ref:workItemEscalationRule"/>
    <Arg name="endOnProvisioningForms" value="ref:endOnProvisioningForms"/>
    <Arg name="approvalAssignmentRule" value="ref:approvalAssignmentRule"/>
    <Arg name="ownerApprovalAssignmentRule" value="ref:ownerApprovalAssignmentRule"/>
    <Arg name="requireCommentsForApproval" value="ref:requireCommentsForApproval"/>
    <Arg name="manualActionsEmailTemplate" value="Pending Manual Changes"/>
    <Arg name="policyViolations" value="ref:policyViolations"/>
    <Arg name="policyScheme" value="ref:policyScheme"/>
    <Arg name="workItemReminderTemplate" value="ref:workItemReminderTemplate"/>
    <Arg name="setPreviousApprovalDecisions" value="ref:setPreviousApprovalDecisions"/>
    <Arg name="selectedPersona" value="ref:selectedPersona"/>
    <Arg name="optimisticProvisioning" value="ref:optimisticProvisioning"/>
    <Arg name="securityOfficerEmailTemplate" value="ref:approvalEmailTemplate"/>
    <Description> Call the OHSU - Approve and Provision Subprocess - Request Access for each Provisioning Project generated in the Split Plan step. 
    </Description>
    <Replicator arg="plan" items="splitPlans"/>
    <Return name="project" to="splitProjects"/>
    <Return name="workItemComments" to="splitWorkItemComments"/>
    <Return name="approvalSet" to="splitApprovalSet"/>
    <WorkflowRef>
      <Reference class="sailpoint.object.Workflow" id="0a56490d8705153281870b2581b30b85" name="OHSU - Approve and Provision Subprocess - Request Access"/>
    </WorkflowRef>
    <Transition to="Assimilate Splits"/>
  </Step>
  <Step action="call:joinLCMProvWorkflowSplits" icon="Task" name="Assimilate Splits" posX="914" posY="63">
    <Arg name="splitProjects" value="ref:splitProjects"/>
    <Arg name="splitApprovalSet" value="ref:splitApprovalSet"/>
    <Arg name="splitWorkItemComments" value="ref:splitWorkItemComments"/>
    <Description> Assimilate all projects returned from the split into the global project. 
    </Description>
    <Transition to="Refresh Identity"/>
  </Step>
  <Step icon="Task" name="Approve and Provision" posX="699" posY="7">
    <Arg name="formTemplate" value="Identity Update"/>
    <Arg name="identityEmailTemplate" value="ref:identityEmailTemplate"/>
    <Arg name="enableRetryRequest" value="ref:enableRetryRequest"/>
    <Arg name="securityOfficerElectronicSignature" value="ref:securityOfficerElectronicSignature"/>
    <Arg name="fallbackApprover" value="ref:fallbackApprover"/>
    <Arg name="endOnManualWorkItems" value="ref:endOnManualWorkItems"/>
    <Arg name="userEmailTemplate" value="ref:userEmailTemplate"/>
    <Arg name="project" value="ref:project"/>
    <Arg name="workItemComments" value="ref:workItemComments"/>
    <Arg name="identityRequestId" value="ref:identityRequestId"/>
    <Arg name="approvalSplitPoint" value="ref:approvalSplitPoint"/>
    <Arg name="source" value="ref:source"/>
    <Arg name="identityDisplayName" value="ref:identityDisplayName"/>
    <Arg name="foregroundProvisioning" value="ref:foregroundProvisioning"/>
    <Arg name="ownerElectronicSignature" value="ref:ownerElectronicSignature"/>
    <Arg name="batchRequestItemId" value="ref:batchRequestItemId"/>
    <Arg name="saveUnmanagedPlan_WithProjectArgument" value="ref:saveUnmanagedPlan_WithProjectArgument"/>
    <Arg name="plan" value="ref:plan"/>
    <Arg name="flow" value="ref:flow"/>
    <Arg name="identityElectronicSignature" value="ref:identityElectronicSignature"/>
    <Arg name="identityName" value="ref:identityName"/>
    <Arg name="approvalSet" value="ref:approvalSet"/>
    <Arg name="filterRejects" value="ref:filterRejects"/>
    <Arg name="ownerEmailTemplate" value="ref:approvalEmailTemplate"/>
    <Arg name="splitProvisioning" value="false"/>
    <Arg name="workItemEscalationTemplate" value="ref:workItemEscalationTemplate"/>
    <Arg name="clearApprovalDecisions" value="ref:clearApprovalDecisions"/>
    <Arg name="noTriggers" value="ref:noTriggers"/>
    <Arg name="requireCommentsForDenial" value="ref:requireCommentsForDenial"/>
    <Arg name="workItemMaxReminders" value="ref:workItemMaxReminders"/>
    <Arg name="requesterEmailTemplate" value="ref:requesterEmailTemplate"/>
    <Arg name="approvalEmailTemplate" value="ref:approvalEmailTemplate"/>
    <Arg name="ticketManagementApplication" value="ref:ticketManagementApplication"/>
    <Arg name="securityOfficerName" value="ref:securityOfficerName"/>
    <Arg name="approvingIdentities" value="ref:approvingIdentities"/>
    <Arg name="workItemHoursTillEscalation" value="ref:workItemHoursTillEscalation"/>
    <Arg name="managerEmailTemplate" value="ref:approvalEmailTemplate"/>
    <Arg name="managerApprovalAssignmentRule" value="ref:managerApprovalAssignmentRule"/>
    <Arg name="launcher" value="ref:launcher"/>
    <Arg name="approvalScheme" value="ref:approvalScheme"/>
    <Arg name="workItemHoursBetweenReminders" value="ref:workItemHoursBetweenReminders"/>
    <Arg name="workItemPriority" value="ref:workItemPriority"/>
    <Arg name="managerElectronicSignature" value="ref:managerElectronicSignature"/>
    <Arg name="approvalMode" value="ref:approvalMode"/>
    <Arg name="trace" value="ref:trace"/>
    <Arg name="workItemEscalationRule" value="ref:workItemEscalationRule"/>
    <Arg name="endOnProvisioningForms" value="ref:endOnProvisioningForms"/>
    <Arg name="approvalAssignmentRule" value="ref:approvalAssignmentRule"/>
    <Arg name="ownerApprovalAssignmentRule" value="ref:ownerApprovalAssignmentRule"/>
    <Arg name="requireCommentsForApproval" value="ref:requireCommentsForApproval"/>
    <Arg name="manualActionsEmailTemplate" value="Pending Manual Changes"/>
    <Arg name="policyViolations" value="ref:policyViolations"/>
    <Arg name="policyScheme" value="ref:policyScheme"/>
    <Arg name="workItemReminderTemplate" value="ref:workItemReminderTemplate"/>
    <Arg name="setPreviousApprovalDecisions" value="ref:setPreviousApprovalDecisions"/>
    <Arg name="selectedPersona" value="ref:selectedPersona"/>
    <Arg name="optimisticProvisioning" value="ref:optimisticProvisioning"/>
    <Arg name="securityOfficerEmailTemplate" value="ref:approvalEmailTemplate"/>
    <Description> Finish any remaining approvals and provision. 
    </Description>
    <Return name="project" to="project"/>
    <Return name="approvalSet" to="approvalSet"/>
    <Return name="workItemComments" to="workItemComments"/>
    <WorkflowRef>
      <Reference class="sailpoint.object.Workflow" id="0a56490d8705153281870b2581b30b85" name="OHSU - Approve and Provision Subprocess - Request Access"/>
    </WorkflowRef>
    <Transition to="Refresh Identity"/>
  </Step>
  <Step action="call:refreshIdentity" condition="ref:doRefresh" icon="Task" name="Refresh Identity" posX="1028" posY="7">
    <Arg name="identityName" value="ref:identityName"/>
    <Arg name="correlateEntitlements" value="true"/>
    <Arg name="refreshIdentityEntitlements" value="true"/>
    <Description> Add arguments as necessary to enable refresh features. Typically you only want this to correlate roles. Don't ask for provisioning since that can result in provisioning policies that need to be presented and it's too late for that. This is only to get role detection and exception entitlements in the cube. 
    </Description>
    <Transition to="Notify"/>
  </Step>
  <Step icon="Task" name="Notify" posX="1131" posY="7">
    <Arg name="approvalScheme" value="ref:approvalScheme"/>
    <Arg name="identityName" value="ref:identityName"/>
    <Arg name="notificationScheme" value="ref:notificationScheme"/>
    <Arg name="userEmailTemplate" value="ref:userEmailTemplate"/>
    <Arg name="approvalSet" value="ref:approvalSet"/>
    <Arg name="policyViolations" value="ref:policyViolations"/>
    <Arg name="workItemPriority" value="ref:workItemPriority"/>
    <Arg name="identityRequestId" value="ref:identityRequestId"/>
    <Arg name="source" value="ref:source"/>
    <Arg name="identityDisplayName" value="ref:identityDisplayName"/>
    <Arg name="trace" value="ref:trace"/>
    <Arg name="requesterEmailTemplate" value="ref:requesterEmailTemplate"/>
    <Arg name="securityOfficerName" value="ref:securityOfficerName"/>
    <Arg name="securityOfficerEmailTemplate" value="ref:securityOfficerEmailTemplate"/>
    <Arg name="plan" value="ref:plan"/>
    <Arg name="flow" value="ref:flow"/>
    <Arg name="managerEmailTemplate" value="ref:managerEmailTemplate"/>
    <Arg name="launcher" value="ref:launcher"/>
    <Description> Call the standard subprocess that will notify the various actors based on notification scheme. 
    </Description>
    <WorkflowRef>
      <Reference class="sailpoint.object.Workflow" id="0a56490d815b1c0381815bdce3a802f0" name="Identity Request Notify"/>
    </WorkflowRef>
    <Transition to="end"/>
  </Step>
  <Step action="call:addMessage" name="Exit On Policy Violation" posX="201" posY="253">
    <Arg name="message" value="Failed due to policy violation(s)"/>
    <Arg name="type" value="Error"/>
    <Transition to="end"/>
  </Step>
  <Step action="call:addMessage" name="Exit On Manual Work Items" posX="364" posY="107">
    <Arg name="message" value="Failed due to manual work item(s)"/>
    <Arg name="type" value="Error"/>
    <Transition to="end"/>
  </Step>
  <Step action="call:addMessage" name="Exit On Provisioning Form" posX="280" posY="178">
    <Arg name="message" value="Failed due to provisioning form"/>
    <Arg name="type" value="Error"/>
    <Transition to="end"/>
  </Step>
  <Step catches="complete" icon="Catches" name="Finalize" posX="1058" posY="308">
    <Arg name="trace" value="ref:trace"/>
    <Arg name="batchRequestItemId" value="ref:batchRequestItemId"/>
    <Arg name="identityName" value="ref:identityName"/>
    <Arg name="autoVerifyIdentityRequest" value="ref:autoVerifyIdentityRequest"/>
    <Arg name="approvalSet" value="ref:approvalSet"/>
    <Arg name="ticketManagementApplication" value="ref:ticketManagementApplication"/>
    <Arg name="project" value="ref:project"/>
    <Arg name="workItemPriority" value="ref:workItemPriority"/>
    <Arg name="identityRequestId" value="ref:identityRequestId"/>
    <Arg name="ticketDataGenerationRule"/>
    <Description> Call the standard subprocess that can audit/finalize the request. 
    </Description>
    <WorkflowRef>
      <Reference cl ass="sailpoint.object.Workflow" id="0a56490d815b1 c0381815bdce3d402f2" name="Identity Request Finalize"/>
    </WorkflowRef>
    <Transition to="end"/>
  </Step>
  <Step icon="Stop" name="end" posX="1131" posY="253"/>
</Workflow>

I believe option #1 isn’t possible even with customizing the workflow. Sending an email to the requester seems like a simpler solution compared to displaying a message on the screen.

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.