Add / remove entitlement Operation

Hi,

my API payload to add entitlement looks like

whenever I need to add a new entitlement, I need to get the list of existing entitlements and then append the new one. Similarly I need for removal, I need to get existing list and remove the entitlement and then send the list in the poyload.

Has anyone implemented this logic?

Hi @chandramohan27

I assume this is a Web Services connector. Since the target API expects the complete entitlement list in the payload rather than only the entitlement being added or removed, you may need to first retrieve the user’s current entitlements from the target system.

One possible approach is to call an endpoint such as /user/{userId} within the rule to fetch the user’s current account data. From the response, extract the existing entitlement list and store it in a Map or ArrayList, depending on the structure of the target API payload.

Then, based on the provisioning operation:

  • For an Add operation, add the newly requested entitlement to the existing list.
  • For a Remove operation, remove the requested entitlement from the existing list.

Once the list is updated, use the complete modified entitlement list to construct the final API payload and send it to the target system.

This is a high-level approach, but it should be achievable using Web Services connector rule logic. You may also need to handle cases such as an empty existing entitlement list, duplicate values during Add operations, and entitlement matching during Remove operations.

@Gopi2000

Thanks for your reply.

we might encounter race condition here .

No, I don’t think it should cause a race condition, as each request will be processed individually. For example, for an entitlement addition, you can capture the AccountRequest and AttributeRequest from the provisioning plan and update the request body accordingly. This approach should work fine.

Hi @chandramohan27 ,

I have implemented similar use case using before operation rule. Below is the rule you can change according to your use case. Change get user API to get all entitlement API in below rule.

import sailpoint.connector.webservices.WebServicesClient;
import sailpoint.connector.webservices.EndPoint;
import sailpoint.connector.ConnectorException;
import sailpoint.object.Application;
import sailpoint.object.ProvisioningPlan;
import sailpoint.object.ProvisioningPlan.AccountRequest;
import sailpoint.object.ProvisioningPlan.AttributeRequest;
import sailpoint.tools.GeneralException;
import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import connector.common.JsonUtil;
import connector.common.Util;
 
log.info("----------------Entering AddEntitlementToUser Rule---------------------");
 
String baseUrl = (String) application.getStringAttributeValue("genericWebServiceBaseUrl");
log.info("-------------Base URL: -------------" + baseUrl);
 
// Initialize variables
String nativeIdentity = "";
List newRoles = new ArrayList();
Map body = requestEndPoint.getBody();
 
// Extract native identity and team_ids from provisioning plan
if (provisioningPlan != null) {
    for (AccountRequest accReq : Util.iterate(provisioningPlan.getAccountRequests())) {
        nativeIdentity = accReq.getNativeIdentity();
        for (AttributeRequest attReq : Util.iterate(accReq.getAttributeRequests())) {
            if ("team_ids".equalsIgnoreCase(attReq.getName())) {
                Object value = attReq.getValue();
                if (value != null) {
                    if (value instanceof List) {
                        for (Object v : (List) value) {
                            if (v != null) {
                                newRoles.add(v.toString()); // normalize to String
                            }
                        }
                    } else {
                        // Handles String, Integer, or any other single object
                        newRoles.add(value.toString());
                    }
                }
            }
        }
    }
}
 
// Construct API endpoint
String getUserApi = baseUrl + "/users/" + nativeIdentity;
log.info("-----------API URL to get user details: ----------------" + getUserApi);
 
// Prepare headers
Map headers = new HashMap();
headers.putAll(requestEndPoint.getHeader());
List allowedStatuses = new ArrayList();
allowedStatuses.add("2**");
 
// Execute GET request
String singleUserResponse = restClient.executeGet(getUserApi, headers, allowedStatuses);
log.info("----------------User details response: --------------" + singleUserResponse);
 
// Parse response
Map singleResponseMap = JsonUtil.toMap(singleUserResponse);
List userDetails = (List) singleResponseMap.get("users");
Map singleUserDetails = (Map) userDetails.get(0);
List existingRoles = (List) singleUserDetails.get("team_ids");
if (existingRoles == null) {
    existingRoles = new ArrayList();
}
 
// Merge roles
existingRoles.addAll(newRoles);

// Deduplicate roles (optional but safe)
Set uniqueRoles = new HashSet(existingRoles);
List mergedRoles = new ArrayList(uniqueRoles);

log.info("----------------Merged team_ids --------------" + mergedRoles);
 
// Prepare final body
Map fullBody = new HashMap();
fullBody.put("team_ids", mergedRoles);
 
Map fullBody2 = new HashMap();
fullBody2.put("user", fullBody);
 
String finalBody = JsonUtil.render(fullBody2);
body.put("jsonBody", finalBody);
requestEndPoint.setBody(body);
 
log.info("---------------Final Body-------------------" + fullBody2);
log.info("---------------Exiting AddEntitlementToUser Rule-------------------");
 
return requestEndPoint;

Hope this will cover your use case.

Regards,

Suraj

You need to use a Before rule for that. no other way arround.

you are talking here in general you need list of ents or for a user?