How to Enforce Approval Only for Specific Roles in LCM Provisioning Workflow

Which IIQ version are you inquiring about?

8.4P2

Please share any images or screenshots, if relevant.

[Please insert images here, otherwise delete this section]

Please share any other relevant files that may be required (for example, logs).

[Please insert files here, otherwise delete this section]

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

Hi all,

I’m working on customizing the LCM Provisioning Workflow in IdentityIQ to enforce approvals only for specific roles — based on classification (e.g. "sensitive" or "privileged").

:white_check_mark: What I did so far:

  • I tried to modify the approvalschema variable that inspects each AttributeRequest and returns an Approval object only if the associated role (Bundle) has a sensitive classification.
  • If no roles match, it correctly returns "none" — this part works well when only one role is assigned.
    here the code:
import sailpoint.object.Bundle;
import sailpoint.object.ProvisioningPlan.AccountRequest;
import sailpoint.object.ProvisioningPlan.AttributeRequest;
import sailpoint.object.Workflow.Approval;
import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;

List approvals = new ArrayList();
List sensitiveClassifications = Arrays.asList("sensitive", "privileged");

if (plan != null && plan.getAccountRequests() != null) {
    for (AccountRequest accountReq : plan.getAccountRequests()) {
        if (accountReq.getAttributeRequests() != null) {
            for (AttributeRequest attrReq : accountReq.getAttributeRequests()) {

                Object value = attrReq.getValue(context);
                String roleName = (value != null) ? value.toString() : null;

                if (roleName != null) {
                    Bundle role = context.getObjectByName(Bundle.class, roleName);
                    if (role != null) {
                        List classifications = role.getClassificationNames();

                        if (classifications != null) {
                            for (String type : sensitiveClassifications) {
                                if (classifications.contains(type)) {
                                    // Only create approval for sensitive role
                                    Approval approval = new Approval();
                                    approval.setOriginalOwner("manager"); // or dynamic owner
                                    approvals.add(approval);
                                    break; // No need to check other classification types
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

// Return approvals only if any were created; otherwise skip approval
return (approvals.isEmpty()) ? "none" : approvals;

:red_exclamation_mark:Problem:

When multiple roles are assigned in the same request:

  • If one role is classified (e.g. "sensitive") and one is not, both end up requiring approval.
  • I suspect this is because the workflow still splits all provisioning items in the Split Plan or Approve and Provision Split step — even the ones I didn’t explicitly create approvals for.

:wrench: What I tried:

  • Filtering the approvalScheme — works fine.

  • Inserting a script step before Split Plan to filter the plan.getAccountRequests() to include only sensitive items. but still not working.

  • Do you have any other suggestions or I’am doing somthing wrong?

hi @Tarek_ICC_AT You’re absolutely right — suspecting that the Split Plan or Approve and Provision Split step is still processing all AccountRequests , even those that didn’t generate an approval. This is because IdentityIQ doesn’t automatically prune the provisioning plan based on the approval scheme — it still includes all items unless explicitly filtered.

You can try below to ensure only sensitive roles go through the approval process, you’ll need to modify the provisioning plan itself before the split step. Here’s what you can do:

  1. Insert a Script step before the Split Plan (or Approve and Provision Split).
  2. In that step, filter out non-sensitive AttributeRequests from the AccountRequests.

Here’s a sample snippet to help:

import sailpoint.object.Bundle;
import sailpoint.object.ProvisioningPlan.AccountRequest;
import sailpoint.object.ProvisioningPlan.AttributeRequest;

List<String> sensitiveClassifications = Arrays.asList("sensitive", "privileged");

if (plan != null && plan.getAccountRequests() != null) {
    Iterator<AccountRequest> acctReqIter = plan.getAccountRequests().iterator();

    while (acctReqIter.hasNext()) {
        AccountRequest acctReq = acctReqIter.next();
        List<AttributeRequest> attrReqs = acctReq.getAttributeRequests();

        if (attrReqs != null) {
            Iterator<AttributeRequest> attrIter = attrReqs.iterator();

            while (attrIter.hasNext()) {
                AttributeRequest attrReq = attrIter.next();
                Object value = attrReq.getValue(context);
                String roleName = (value != null) ? value.toString() : null;

                if (roleName != null) {
                    Bundle role = context.getObjectByName(Bundle.class, roleName);
                    if (role != null) {
                        List<String> classifications = role.getClassificationNames();
                        if (classifications != null && !Collections.disjoint(classifications, sensitiveClassifications)) {
                            continue; // Keep this request
                        }
                    }
                }
                // Remove non-sensitive AttributeRequest
                attrIter.remove();
            }
        }

        // Remove AccountRequest if it has no AttributeRequests left
        if (acctReq.getAttributeRequests().isEmpty()) {
            acctReqIter.remove();
        }
    }
}

Hi @haideralishaik ,

Thank you for the solution.
I still have one question regarding the approvalScheme and approvalSplitPoint variables:

Should I assign a specific value to them, or can I leave them empty?
Also, is it enough to only add the filter step before the split, or do I still need to set an initializer value for the approvalScheme variable?

I’d like to understand if the filtering logic alone is sufficient, or if the approval flow still depends on the values defined in approvalScheme and approvalSplitPoint.

Thank you again!

hi @Tarek_ICC_AT

  1. Yes, you should still set the approvalScheme variable — even if you’re filtering the plan beforehand. The filtering step ensures only sensitive items remain, but the approval scheme is still what triggers the actual approval process.

  2. The filtering step alone is not enough — it prevents unnecessary items from reaching the approval stage, but the approvalScheme is what tells IdentityIQ what to do with the remaining items.

Hi @haideralishaik ,
I tried the suggested solution to filter approvals based on role classification. I added the filtering script in the approvalSchema and also inserted a filtering step before the Split Plan. However, I still receive approvals for both roles — even when only one of them has a classification.

Could it be related to the approvalMode setting?
Do I need to change it from parallel to something else to avoid this issue?

Thanks in advance,

Hi @Tarek_ICC_AT
If you’re still seeing approvals for both roles, even when only one is classified, you’re right to look into the approvalMode — it can definitely influence behavior.

I would check:

  1. approvalMode setting:
  • If it’s set to "parallel", IdentityIQ may be treating each item independently and triggering approvals for all, regardless of your filtering.
  • Try switching it to "serial" or "combined" to see if that changes the behavior. These modes can help ensure that only the items that actually require approval go through the approval process.
  1. Double-check the filtering logic:
  • Make sure the filtering step is actually removing the non-sensitive AttributeRequests from the plan — not just skipping them in logic.
  • You can log the contents of the plan after filtering to confirm what’s left before the split step.
  1. ApprovalScheme return value:
  • Ensure that your approvalScheme logic returns "none" when no approvals are needed. If it returns an empty list or null, IIQ might still default to creating approvals.

Hi @haideralishaik ,

The reason it did not work is because the approvalSchema needs to contain two values, such as manager and owner. Additionally, the filter script added to the approvalSchema should be assigned to the approvalSplitPoint variable.

The approvalSplitPoint should then check whether it matches one of the two values in the approvalSchema to determine whether the approvalItem should be split, as there are two distinct options.

The script you provided works very well for the filter steps.
Thank you for your support!

1 Like