Limit each Identity Request in SailPoint IIQ to not carry more than 20 (exclude) request items

I hope all doing good. There was an issue when an end user submitted an Identity Request in SAM with more than 20 request items (Add Access) at a time. There was an incident reported where an end user submitted more than 100 request items at a time, which caused the UI server to crash repeatedly for more than a week.
Therefore, we have implemented a solution to enforce a maximum request item limit, which restricts each Identity Request in SAM to contain no more than 20 request items at a time. We are able to check only assigned roles, “Not entitlements”.

is there a method to check entitlements like getAssignedRoles() method?

We need to check entitlements also along with roles since use raises a request for both. Please advise.

Below is the code which will only check roles, not entitlements

import java.util.List;
import sailpoint.tools.Util;
import java.util.ArrayList;
import sailpoint.object.Identity;
import sailpoint.object.Bundle;
import sailpoint.object.PolicyViolation;

log.debug(“Inside (Add Access) Policy Violation”);
PolicyViolation violation = null;
boolean vflag = false;
String desc = null;

try {
Identity reqIdentity = identity;
Identity dbIdentity = context.getObjectByName(Identity.class, identity.getName());

List reqIdRoles = reqIdentity.getAssignedRoles();
List dbIdRoles = dbIdentity.getAssignedRoles();

if((reqIdRoles != null && !reqIdRoles.isEmpty()) && (dbIdRoles != null && !dbIdRoles.isEmpty())) {
  reqIdRoles.removeAll(dbIdRoles);
}


if (reqIdRoles.size() > 20) {
  vflag = true;
  desc = "You can not request for more that 20 request Items (Add Access) at a Time";
}

if (vflag) {
  violation = new PolicyViolation();
  violation.setActive(true);
  violation.setIdentity(identity);
  violation.setPolicy(policy);
  violation.setConstraint(constraint);
  violation.setDescription(desc);
  violation.setStatus(sailpoint.object.PolicyViolation.Status.Open);
}
return violation;

}

catch (Exception e )
{
e.printStackTrace();
}

Any update on this please ?

import java.util.List;
import sailpoint.tools.Util;
import java.util.ArrayList;
import sailpoint.object.Identity;
import sailpoint.object.Bundle;
import sailpoint.object.PolicyViolation;
import sailpoint.object.Attributes;
import sailpoint.object.Link;
import sailpoint.api.IdentityService;

log.debug(“Inside (Add Entitlements) Policy Violation”);
PolicyViolation violation = null;
boolean vflag = false;
String desc = null;

Map entAttrMap=null;
Map oldentAttrMap=null;
int entAppChanges=0;

List valuesAll=new ArrayList();
List valuesAllOld=new ArrayList();

Identity reqIdentity = identity;
Identity dbIdentity = context.getObjectByName(Identity.class, identity.getName());

List newLinks = reqIdentity.getLinks();

if (newLinks != null && !newLinks.isEmpty()){
for (Link link : newLinks){
Attributes entAttributes = link.getEntitlementAttributes();
entAttrMap = entAttributes.getMap();

  for (Map.Entry entry : entAttrMap.entrySet()){
    valuesAll.add(entry.getKey()+entry.getValue());
  }

  if(entAttrMap !=null &&!entAttrMap.isEmpty()){
    IdentityService idService = new IdentityService(context);
    Link oldLinks = idService.getLink(dbIdentity, context.getObjectByName(Application.class, link.getApplicationName()),link.getInstance(),link.getNativeIdentity());
    if(null != oldLinks){
      Attributes oldEntAttributes = oldLinks.getEntitlementAttributes();
      oldentAttrMap = oldEntAttributes.getMap();
    }

    for (Map.Entry entry1 : oldentAttrMap.entrySet()){
      valuesAllOld.add(entry1.getKey()+entry1.getValue());
    }

  }
}

}

log.error(“valuesAll=”+valuesAll);
log.error(“valuesAllOld=”+valuesAllOld);
valuesAll.removeAll(valuesAllOld);
log.error(“Requested Entitlements List=”+valuesAll);
entAppChanges=valuesAll.size();
log.error(“Requested Entitlements Size=”+entAppChanges);

if (entAppChanges > 5) {
vflag = true;
desc = “You can not request for more that 20 request Items (Add Access) at a Time”;
}

if (vflag) {
violation = new PolicyViolation();
violation.setActive(true);
violation.setIdentity(identity);
violation.setPolicy(policy);
violation.setConstraint(constraint);
violation.setDescription(desc);
violation.setStatus(sailpoint.object.PolicyViolation.Status.Open);
}
return violation;

I tried to do it for entitlements. it is working only on links(number applications). could you please check help me here

Hi @Venu1010

I just want to clarify your requirement. You code seems to be checking the number or roles already assigned to an identity. I understand that this is not what you need. You want to limit the amount of roles or entitlements users can request at one time, right?
If so, one what to do that is modifying the workflow that is triggered by IIQ request gui which ootb is LCM Provisioning. This workflow gets a provisioning plan as a result of request. You could add custom step at the beginning of the workflow to check the plan and possible modify it or stop the execution possibly informing the user.
Let me know if this puts you on the right course?
Regards
Alek

Yes that is correct I want to limit the amount of entitlements users can select at one time. For limiting roles is already done via advanced policy violation using getAssignedRoles() method. We donot want to touch global workflow. So we want to limit through policy for entitlements as well . I ma not getting method to pull requested entitlements under advanced policy. Could you please help.

Sample code working for Roles restriction. Attached
Violation-Limit_the_number_of_requestItems_in_each_Identity_Request.xml (1.0 KB)

1 Like

Sorry, the xml you provided gives error on download. Nevertheless, if you are already checking the roles in policy you can just get the links from the tested identity(if they are available) and from links you can manually extract the entitlements (which attributes are entitlement attributes you can get from schema definition in application)

This could work but examining provisioning plan in the workflow would be soooo much simpler.

Regards
Alek

ps It is pretty normal to customize LCM Provisioning workflow to you needs.

Could you please let me know where I need to change in LCM Provisioning workflow

do u have the sample code to fetch details.

Here is more less how you would count number of item requested. This should be put in a step right at the beginning of LM Provisioning:

int count = 0;
        for (ProvisioningPlan.AccountRequest accountRequest: plan.getAccountRequests()) {
            if (ProvisioningPlan.APP_IIQ.equals(accountRequest.getApplication())) {
                for (ProvisioningPlan.AttributeRequest attributeRequest: accountRequest.getAttributeRequests(ATT_ASSIGNED_ROLES)) {
                    // count ++ attributeRequest.getValue(), this can be list or single value
                }
            } else {
                for (ProvisioningPlan.AttributeRequest attributeRequest: accountRequest.getAttributeRequests()) { // in this case these should only be attributes related to managedAttributes
                    // count ++ attributeRequest.getValue(), this can be list or single value
                }
            }
        }
1 Like