Remove Entitlement Stickiness for a Webservice source

Hi,

For a webservice application while trying to create an account with roles is failing. There is a before provisioning rule added to remove entitlement stickiness.

In the rule I used a logic to remove stickiness at the time of creation and modification as below:

if (plan != null) {
List accountRequests = plan.getAccountRequests();
List entNames = application.getEntitlementAttributeNames();

   ) {
					for (AttributeRequest req : attrRequests) {
						if (null != req && Provis if (null != accountRequests) {
        for (AccountRequest accountRequest : accountRequests) {
            if (null != accountRequest && (accountRequest.getOp().equals(ProvisioningPlan.ObjectOperation.Create) || 
            accountRequest.getOp().equals(ProvisioningPlan.ObjectOperation.Modify))) {
                List attrRequests =  accountRequest.getAttributeRequests();
				if (null != attrRequestsioningPlan.Operation.Add.equals(req.getOperation())) {
							//check if it is entitlement request
							if (entNames.contains(req.getName())){								
								//set assignment to false for Added entitlement
								req.setAssignment(false);
								log.error("Rule-Account-Flag-false");
								}else {
								log.error("Rule-Account-Not-Found");
								}
							} 
						}
					} 
				}
			} 
                } 

Correct me iin the rule If I am doing something wrong in it or share me a rule that removes entitlement stickiness.

TIA

Hi @kanusha9 ,

Youre doing wrong in rule first iterating attribute requests and then account requests in your rule.

follow below code for your reference to avoid entitlement stickyness. modify this as per your rule logic

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import sailpoint.tools.GeneralException;
import sailpoint.tools.Util;
import sailpoint.object.Application;
import sailpoint.object.Identity;
import sailpoint.object.ProvisioningPlan;
import sailpoint.object.ProvisioningPlan.AccountRequest;
import sailpoint.object.ProvisioningPlan.AttributeRequest;

/* ================= MAIN ================= */
try {

if (plan != null) {

    Identity identity = plan.getIdentity();

    for (AccountRequest accountRequest : plan.getAccountRequests()) {

        String nativeIdentity = accountRequest.getNativeIdentity();             

        /* =================CREATE Or MODIFY ================= */
        if (ProvisioningPlan.ObjectOperation.Modify.equals(accountRequest.getOp()) || ProvisioningPlan.ObjectOperation.Create.equals(accountRequest.getOp())) {

            /* ===== HANDLE STICKY ENTITLEMENTS ===== */
            List entNames = application.getEntitlementAttributeNames();

            List attributeRequests = accountRequest.getAttributeRequests();

            if (attributeRequests != null) {
                for (AttributeRequest req : attributeRequests) {

                    if (req == null) continue;

                    if (entNames.contains(req.getName())) {

                        if (ProvisioningPlan.Operation.Add.equals(req.getOperation())) {
                            req.put("assignment", false); // prevent stickiness
                        }

                        if (ProvisioningPlan.Operation.Remove.equals(req.getOperation())) {
                            req.put("assignment", true); // ensure removal persists
                        }
                    }
                }
            }
        }

      
    }
}

} catch (Exception ex) {
log.error("Error in Docusign rule: ", ex);
}

Your overall approach looks correct. Setting req.setAssignment(false) on entitlement Add requests in a Before Provisioning Rule is the standard way to prevent entitlement stickiness in ISC.

A few observations on your code:

  1. Check the operation type

    • Make sure you’re checking for ProvisioningPlan.AccountRequest.Operation.Create and Modify (or the appropriate AccountRequest operation enum) rather than ObjectOperation. Depending on the rule context, using the wrong enum can cause the condition to never match.
  2. Verify entitlement attribute names

    • application.getEntitlementAttributeNames() returns the application’s entitlement attributes. Add logging to confirm that req.getName() matches one of those values.

    • I’ve seen cases where the entitlement attribute name in the plan differs from what is configured on the source.

  3. Role-based requests

    • If you’re provisioning roles rather than direct entitlements, the role may be expanded into entitlements later in the provisioning process. In that case, the entitlement requests may not yet exist when the Before Provisioning Rule executes.
  4. Add more logging

    • Log:

      • Account operation

      • Attribute request name

      • Attribute request operation

      • Assignment value before and after modification

    • This will help verify whether the rule is actually touching the entitlement requests.

  5. Account creation scenario

    • Some connectors handle Create requests differently from Modify requests. Verify in the provisioning plan debug output that entitlement AttributeRequests are present during account creation.

Example logic:

for (AccountRequest ar : plan.getAccountRequests()) {
    if (ar.getOp() == AccountRequest.Operation.Create ||
        ar.getOp() == AccountRequest.Operation.Modify) {

        for (AttributeRequest req : ar.getAttributeRequests()) {

            if (ProvisioningPlan.Operation.Add.equals(req.getOperation()) &&
                entNames.contains(req.getName())) {

                req.setAssignment(false);
                log.error("Setting assignment=false for entitlement: " + req.getName());
            }
        }
    }
}

If the account creation is failing, I would also review the provisioning plan XML and connector logs. The failure may not be related to setAssignment(false) itself but rather to how the Web Services connector is processing the role/entitlement payload during Create operations.

Hi Anusha,
In your rule, the approach is correct, but the code structure looks broken because some conditions are merged incorrectly. Also, I would suggest applying this only for entitlement attribute requests where operation is Add, and only after confirming the attribute name is part of the source entitlement attributes.

You can try the below logic in the Before Provisioning Rule:

if (plan != null && application != null) {

List accountRequests = plan.getAccountRequests();

List entitlementAttrs = application.getEntitlementAttributeNames();

if (accountRequests != null && entitlementAttrs != null) {

    for (AccountRequest accountRequest : accountRequests) {

        if (accountRequest != null &&

            (ProvisioningPlan.ObjectOperation.Create.equals(accountRequest.getOp()) ||

             ProvisioningPlan.ObjectOperation.Modify.equals(accountRequest.getOp()))) {

            List attrRequests = accountRequest.getAttributeRequests();

            if (attrRequests != null) {

                for (AttributeRequest attrReq : attrRequests) {

                    if (attrReq != null &&

                        ProvisioningPlan.Operation.Add.equals(attrReq.getOperation()) &&

                        entitlementAttrs.contains(attrReq.getName())) {

                        attrReq.setAssignment(false);

                        log.error("Entitlement stickiness removed for: " + attrReq.getName());

                    }

                }

            }

        }

    }

}

}

This should remove entitlement stickiness for added entitlement requests during create/modify. Also validate that the Web Services source entitlement attribute name exactly matches the attribute request name, for example roles, groups, or the configured entitlement schema attribute.

Hi @kanusha9

Can you please once check this referred link for code. ( Removing Requested (Sticky) Entitlements Using a BeforeProvisioning Rule)