Remove Entitlement Web Service

Hi All,
I have integrated one Web Service application with our tenant.
For remove entitlement we are having API where we need to PATCH the roles again, removing that role which we want to revoke.

eg.

User is having role1, role2 and role3 assigned. If role2 is getting revoked then we are using Update user API and PATCH the body

{
    "roles": ["role1" , "role3"]
}

From postman this is working fine, how to implement this in Sailpoint?
Did anyone came across this scenario . What could be done in this situation?
Thanks

Hi @shikhadeliveroo,

I just wanted to clarify something—when one role is revoked, it seems like the system also revokes other associated roles. In such cases, do we need to manually patch and update the other roles to reassign them?

Is my understanding correct? Could you help me with a clearer query or explanation?

Thanks!

No that is not the case. Let me clarify.

So we are not having remove entitlement API. We can do it using update user only. And In Update user API we need to patch the body with all the roles except ‘the revoked one’
In simple terms we need to override the existing roles.

For this I would use a combination of two different HTTP operations and a before operation rule.

HTTP Operation 1 is set to ‘remove entitlement’ type, but actually calls out to the Webservice API to get all entitlements of the current user. Ensure you properly map the response so you can use it in the next operation.

HTTP Operation 2 is your ‘Patch’ operation type, with type ‘get object’ and should have as it’s parent the previous operation. The body can be something like $plan.groups$ (depending on what you call your entitlements in the schema)

Then you create a before operation rule that takes what is in the body and what was retrieved from the first operation and then remove from the response of HTTP operation 1 whatever is in your $plan.groups$.

Here is an example of something I created for a similar use case:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import connector.common.JsonUtil;
import connector.common.Util;
import sailpoint.object.ProvisioningPlan;
import sailpoint.object.ProvisioningPlan.AccountRequest;

Map body = requestEndPoint.getBody();
String jsonBody = (String) body.get("jsonBody");

List capabilities = new ArrayList();
List currentCapabilities = oldResponseMap.get("capabilities");
currentCapabilities.remove(jsonBody);

for (String cap: currentCapabilities) {
    capabilities.add(cap);
}


Map authUserMap = new HashMap();
authUserMap.put("op", "replace");
authUserMap.put("path","/capabilities");
authUserMap.put("value",capabilities);

List authUserList = new ArrayList();
authUserList.add(authUserMap);

String finalBody = JsonUtil.render(authUserList);
body.put("jsonBody", finalBody);
requestEndPoint.setBody(body);

@sauvee I am not able to understand what we are doing in operation 2

Operation 1 is to get from the web app the access you currently have.

Operation 2 is to:

  • with a rule, calculate the acces you should have, removing from the list of operation 1 what is in the plan
  • The to perform a patch with the outcome of that rule.

@shikhadeliveroo have you configured your patch request in remove entitlement operation properly?
Can help with screenshots to verify

Hi @shikhadeliveroo ,

For this you can use the Before Operation rule, in which you call an another API to get the user’s assigned entitlements, compare them with the requested entitlement for removal, and use the remaining entitlements in the PATCH body in update user API.

Thanks.

Hi @sauvee I am trying to write single rule for all. I am adding the rule here. I am getting error
Error in method invocation: Method executeGet(java.lang.String, java.util.HashMap) not found in class\u0027sailpoint.connector.webservices.WebServicesClient\u0027 : at Line: 50 : in file: inline evaluation of: ``import java.util.; import sailpoint.tools.; import connector.common.JsonUtil; . . . \u0027\u0027 : restClient .executeGet ( getUrl , headers ) \n BSF info: SplunkRoleRemove at line: 0 column: columnNo"]

Checked everywhere on executeGet not sure why getting this error, do you have any idea ?

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Rule name="SplunkRoleRemoval" type="WebServiceBeforeOperationRule">
    <Description>Removes a role and updates user roles in Splunk</Description>
    <Source><![CDATA[

import java.util.*;
import sailpoint.tools.*;
import connector.common.JsonUtil;
import sailpoint.object.*;
import connector.common.Util;
import org.json.JSONObject;
import org.json.JSONArray;

log.debug("WSBO Rule Started");

try {
    // STEP 1: Retrieve the userId and role to remove from the provisioning plan
    String userId = null;
    String roleToRemove = null;

    if (provisioningPlan != null) {
        for (AccountRequest accReq : Util.iterate(provisioningPlan.getAccountRequests())) {
            userId = accReq.getNativeIdentity();
            log.debug("UserId to update: " + userId);
            for (ProvisioningPlan.AttributeRequest attReq : Util.iterate(accReq.getAttributeRequests())) {
                String attrName = attReq.getName();
                if ("roles".equalsIgnoreCase(attrName)) {
                    roleToRemove = (String) attReq.getValue();
                }
            }
        }
    }

    if (userId == null || roleToRemove == null) {
        throw new IllegalArgumentException("UserId or role to remove not found in the provisioning plan.");
    }

    log.debug("Role to remove: " + roleToRemove);

    // STEP 2: Get the user's current roles from Splunk via API (GET)
    String bearerToken = "xxxx";  // Use your actual token
    String baseUrl = "xxxxxx";
    String getUrl = baseUrl + userId;  // Full URL to call the API with userId

    // Headers setup
    Map headers = new HashMap();
    headers.put("Authorization", "Bearer " + bearerToken);

    // RestClient setup
    Map args = new HashMap();
    args.put(WebServicesClient.ARG_URL, baseUrl);  // Set the base URL
    restClient.configure(args);  // Configure the restClient with base URL

    // STEP 3: Execute GET request to retrieve current roles using `executeGet` method
    String response = restClient.executeGet(getUrl, headers);  // This is the key change

    // Parse the response JSON to get the roles
    JSONObject jsonResponse = new JSONObject(response);
    JSONArray currentRolesArray = jsonResponse.getJSONArray("roles");

    List updatedRoles = new ArrayList();
    for (int i = 0; i < currentRolesArray.length(); i++) {
        String role = currentRolesArray.getString(i);
        if (!role.equalsIgnoreCase(roleToRemove)) {
            updatedRoles.add(role);
        }
    }

    // STEP 4: Create PATCH body to update the roles in Splunk
    Map updatePayload = new HashMap();
    updatePayload.put("roles", updatedRoles);

    // Convert the payload to JSON
    String jsonPayload = JsonUtil.render(updatePayload);
    log.debug("Final PATCH Payload for Splunk API: " + jsonPayload);

    // STEP 5: Send the PATCH request to Splunk API to update roles
    String patchUrl = baseUrl + userId;
    String patchResponse = restClient.executePatch(patchUrl, jsonPayload, headers);

    log.debug("Splunk API PATCH Response: " + patchResponse);

    // STEP 6: Set the updated payload to the request body
    Map body = requestEndPoint.getBody();  // Access the existing requestEndPoint
    body.put("jsonBody", jsonPayload);
    requestEndPoint.setBody(body);  // Set the updated body

} catch (Exception e) {
    log.debug("Error in WebServiceBeforeOperationRule: " + e.getMessage());
    throw e; // Re-throw the exception to indicate failure in the rule
}

return requestEndPoint;

]]></Source>
</Rule>

Hi @shikhadeliveroo ,

Please try with the below code:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Rule name="SplunkRoleRemoval" type="WebServiceBeforeOperationRule">
    <Description>Removes a role and updates user roles in Splunk</Description>
    <Source><![CDATA[

import java.util.*;
import sailpoint.tools.*;
import connector.common.JsonUtil;
import sailpoint.object.*;
import connector.common.Util;
import org.json.JSONObject;
import org.json.JSONArray;

log.debug("WSBO Rule Started");

try {
    // STEP 1: Retrieve the userId and role to remove from the provisioning plan
    String userId = null;
    String roleToRemove = null;

    if (provisioningPlan != null) {
        for (AccountRequest accReq : Util.iterate(provisioningPlan.getAccountRequests())) {
            userId = accReq.getNativeIdentity();
            log.debug("UserId to update: " + userId);
            for (ProvisioningPlan.AttributeRequest attReq : Util.iterate(accReq.getAttributeRequests())) {
                String attrName = attReq.getName();
                if ("roles".equalsIgnoreCase(attrName)) {
                    roleToRemove = (String) attReq.getValue();
                }
            }
        }
    }

    if (userId == null || roleToRemove == null) {
        throw new IllegalArgumentException("UserId or role to remove not found in the provisioning plan.");
    }

    log.debug("Role to remove: " + roleToRemove);

    // STEP 2: Get the user's current roles from Splunk via API (GET)
    String bearerToken = "xxxx";  // Use your actual token
    String baseUrl = "xxxxxx";
    String getUrl = baseUrl + userId;  // Full URL to call the API with userId

    // Headers setup
    Map headers = new HashMap();
    headers.put("Authorization", "Bearer " + bearerToken);

    // RestClient setup
    Map args = new HashMap();
    args.put(WebServicesClient.ARG_URL, baseUrl);  // Set the base URL
    restClient.configure(args);  // Configure the restClient with base URL
	
	List allowedStatuses = new ArrayList(); 
	allowedStatuses.add("2**");

    // STEP 3: Execute GET request to retrieve current roles using `executeGet` method
    String response = restClient.executeGet(getUrl, headers, allowedStatuses);  // This is the key change

    // Parse the response JSON to get the roles
    JSONObject jsonResponse = new JSONObject(response);
    JSONArray currentRolesArray = jsonResponse.getJSONArray("roles");

    List updatedRoles = new ArrayList();
    for (int i = 0; i < currentRolesArray.length(); i++) {
        String role = currentRolesArray.getString(i);
        if (!role.equalsIgnoreCase(roleToRemove)) {
            updatedRoles.add(role);
        }
    }

    // STEP 4: Create PATCH body to update the roles in Splunk
    Map updatePayload = new HashMap();
    updatePayload.put("roles", updatedRoles);

    // Convert the payload to JSON
    String jsonPayload = JsonUtil.render(updatePayload);
    log.debug("Final PATCH Payload for Splunk API: " + jsonPayload);

    // STEP 5: Send the PATCH request to Splunk API to update roles
    String patchUrl = baseUrl + userId;
    String patchResponse = restClient.executePatch(patchUrl, jsonPayload, headers);

    log.debug("Splunk API PATCH Response: " + patchResponse);

    // STEP 6: Set the updated payload to the request body
    Map body = requestEndPoint.getBody();  // Access the existing requestEndPoint
    body.put("jsonBody", jsonPayload);
    requestEndPoint.setBody(body);  // Set the updated body

} catch (Exception e) {
    log.debug("Error in WebServiceBeforeOperationRule: " + e.getMessage());
    throw e; // Re-throw the exception to indicate failure in the rule
}

return requestEndPoint;

]]></Source>
</Rule>

Thanks,
Rohit.

I think you need to change this line:

String response = restClient.executeGet(getUrl, headers);

You also need to provide the allowedStatuses. Please refer to the javaDocs: