provisioning plan with op="Remove" won’t update the Identity’s capabilities because IIQ doesn’t treat them as account entitlements ,they’re managed directly on the Identity.
Capabilities in SailPoint IIQ are not entitlements – they are attributes stored directly on the Identity object.
Because of this, a ProvisioningPlan with op="Remove" will not update/remove them in IIQ.
To remove capabilities, we need to update the Identity object directly. The below code you can try and adjust in your workflow or any adhoc rule based on your requirement.
import sailpoint.object.Identity;
// Get identity
Identity identity = context.getObjectByName(Identity.class, "jdoe");
if (identity != null) {
// Remove all capabilities
identity.setCapabilities(null);
// OR remove a specific one
// identity.remove("<capabilityObject>");
context.saveObject(identity);
context.commitTransaction();
log.debug("Capabilities updated for: " + identity.getName());
}
identity.setCapabilities(null) → It clears all capabilities
Identity id = plan.getIdentity();
List capabilities = id.getCapabilities();
if (id.getCapabilities() != null)
{
log.debug("Removing Capabilities found: " + capabilities.size());
log.debug("Removing Capabilities: " + capabilities.toString());
for (Capability cap : capabilities)
{
log.debug("Removing Capability: " + cap.getName());
id.remove(cap);
context.saveObject(id);
context.commitTransaction();
log.debug("Removed Capability: " + cap.getName());
}
}
and I ended up getting a weird error:
2025-09-23 10:16:49,597 DEBUG Thread-208 CIBC_Rapid_Setup_Leaver:-1 - Entering Remove Capabilities Step
2025-09-23 10:16:49,598 DEBUG Thread-208 CIBC_Rapid_Setup_Leaver:-1 - Removing Capabilities found: 1
2025-09-23 10:16:49,598 DEBUG Thread-208 CIBC_Rapid_Setup_Leaver:-1 - Removing Capabilities: [sailpoint.object.Capability@7e54a91b[id=28ec05305d7ab722015d7abb320a00e9,name=capabiltytest]]
2025-09-23 10:16:49,601 DEBUG Thread-208 CIBC_Rapid_Setup_Leaver:-1 - Removing Capability: capabiltytest
2025-09-23 10:16:49,648 DEBUG Thread-208 CIBC_Rapid_Setup_Leaver:-1 - Removed Capability: capabiltytest
2025-09-23 10:16:49,648 ERROR Thread-208 org.apache.bsf.BSFManager:451 - Exception:
java.security.PrivilegedActionException: null
at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_51]
at org.apache.bsf.BSFManager.eval(BSFManager.java:442) [bsf.jar:?]
at sailpoint.server.BSFRuleRunner.runScript(BSFRuleRunner.java:347) [identityiq.jar:8.3p3 Build d5deab2519b-20230629-092050]
at sailpoint.server.InternalContext.runScript(InternalContext.java:1296) [identityiq.jar:8.3p3 Build d5deab2519b-20230629-092050]
at sailpoint.server.ScriptletEvaluator.doScript(ScriptletEvaluator.java:263) [identityiq.jar:8.3p3 Build d5deab2519b-20230629-092050]
at sailpoint.server.ScriptletEvaluator.evalSource(ScriptletEvaluator.java:71) [identityiq.jar:8.3p3 Build d5deab2519b-20230629-092050]
at sailpoint.api.Workflower.evalSource(Workflower.java:5932) [identityiq.jar:8.3p3 Build d5deab2519b-20230629-092050]
at sailpoint.api.Workflower.advanceStep(Workflower.java:5171) [identityiq.jar:8.3p3 Build d5deab2519b-20230629-092050]
at sailpoint.api.Workflower.advance(Workflower.java:4558) [identityiq.jar:8.3p3 Build d5deab2519b-20230629-092050]
at sailpoint.api.Workflower.startCase(Workflower.java:3144) [identityiq.jar:8.3p3 Build d5deab2519b-20230629-092050]
at sailpoint.api.Workflower.launchInner(Workflower.java:2813) [identityiq.jar:8.3p3 Build d5deab2519b-20230629-092050]
at sailpoint.api.Workflower.launch(Workflower.java:2666) [identityiq.jar:8.3p3 Build d5deab2519b-20230629-092050]
at sailpoint.api.Workflower.launch(Workflower.java:2500) [identityiq.jar:8.3p3 Build d5deab2519b-20230629-092050]
at sailpoint.request.WorkflowRequestExecutor.execute(WorkflowRequestExecutor.java:177) [identityiq.jar:8.3p3 Build d5deab2519b-20230629-092050]
at sailpoint.request.RequestHandler.run(RequestHandler.java:163) [identityiq.jar:8.3p3 Build d5deab2519b-20230629-092050]
Caused by: org.apache.bsf.BSFException: BeanShell script error: bsh.EvalError: Sourced file: inline evaluation of: ``import org.apache.log4j.Logger; import sailpoint.object.Capability; . . . '' unknown error: null : at Line: 12 : in file: inline evaluation of: ``import org.apache.log4j.Logger; import sailpoint.object.Capability; . . . '' : if ( id .getCapabilities ( ) != null ) {
BSF info: script at line: 0 column: columnNo
The code executes, and then I get an error about id.getCapabilities() not being decypherable AFTER the code is complete. If I remove the null check, the code works (unless capabilities is null). If I have multiple capabilities, only the first is removed. A try block resulted in the error being on the try. I tried setCapabilities(null) and that errored as well. Any thoughts?
@AJGibson76 In this code , you are doing a commitTransaction in a for loop that is not recommended. In this case, only the first object will get removed and gives you a null pointer after that. Instead use the below code.
Identity id = plan.getIdentity();
List capabilities = id.getCapabilities();
if (id.getCapabilities() != null)
{
log.debug("Removing Capabilities found: " + capabilities.size());
log.debug("Removing Capabilities: " + capabilities.toString());
for (Capability cap : capabilities)
{
log.debug("Removing Capability: " + cap.getName());
id.remove(cap);
context.saveObject(id);
log.debug("Removed Capability: " + cap.getName());
}
context.commitTransaction();
}
So the commit makes the list null? If so, why am I not getting a null pointer error? I’m getting the message I normally get when the code can not be parsed. Also, I get the error even when there is only one object in the list (I get the for loop accesses it?)