Before Provisioning Rule to Add an Entitlement and Remove an Existing Entitlement

Hello All,

We have a requirement to validate AD group requests based on their Organizational Unit (OU). Specifically, if a user requests access to a group that belongs to a particular OU, we need to check whether they already have access to any other group within the same OU. If so, the existing entitlement should be removed before provisioning the newly requested one.

To implement this logic, I have written a Before Provisioning (BP) Rule. I’ve included extensive logging for debugging and have verified that the rule executes correctly up to the final log statement. The provisioning plan is generated and visible in the UI. However, the request ultimately fails with a generic unknown error: null.

I would appreciate assistance in identifying the issue within the code. Below is the code.

log.debug("Before Provisioning Rule : singleEntitlement : Start of the Code");

//Variables used 

List appIds = new ArrayList(); 

appIds.add("OU=MNE,OU=PRODUCTION,OU=WS_SRIMS,OU=CAPACT,OU=group,OU=APP13509"); 

appIds.add("OU=PlanviewPPM,OU=AzureApp"); 

appIds.add("OU=APP21744_PROD,OU=AzureApp"); 

appIds.add("OU=BPS,OU=group,OU=APP13491"); 

appIds.add("OU=group,OU=app13623");



String ENT_ATTR_NAME = "memberOf"; 

String existingmatchingEntitlement = null; 

String matchingAppId = null; 

String id = null; 

Object attributeValue = null;

String attrvalue = null;



//Reading the provisioning plan 

if (plan != null) {

  Identity identity = plan.getIdentity();

  List accountRequests = plan.getAccountRequests();

  if (accountRequests != null && accountRequests.size() > 0 && identity != null) {

    for (AccountRequest accountRequest: accountRequests) {

      log.debug("Before Provisioning Rule : singleEntitlement :  Account Request is : " + accountRequests);

      if (accountRequest != null) {

        //Searching for attributeRequest groups as per schema

        for (AttributeRequest attributes: accountRequest.getAttributeRequests()) {

          log.debug("Before Provisioning Rule : singleEntitlement : Attribute Request  is : " + attributes);

          if (attributes != null) {



            String attributeName = attributes.getName();

            if (attributeName.equals(ENT_ATTR_NAME)) {

              log.debug("Before Provisioning Rule : singleEntitlement : attributeName is : " + attributeName);

               attributeValue = attributes.getValue();

              log.debug("Before Provisioning Rule : singleEntitlement : attributeValue is : " + attributeValue);



              if (attributeValue != null) {

                if (AccountRequest.Operation.Modify.equals(accountRequest.getOperation())) {

                  log.debug("Before Provisioning Rule : singleEntitlement : Entered the Account Request Operation Modify");



                  if ((ProvisioningPlan.Operation.Add).equals(attributes.getOperation())) {

                    log.debug("Before Provisioning Rule : singleEntitlement : Entered the Attribute Request Operation Add");



                    for (Object appId: appIds) {

                      log.debug("Before Provisioning Rule : singleEntitlement : appId is :" + appId);



                      id = appId.toString();

                      log.debug("Before Provisioning Rule : singleEntitlement : id converted to string is :" + id);



                       attrvalue = attributeValue.toString();

                      log.debug("Before Provisioning Rule : singleEntitlement : attrvalue is : " + attrvalue);

                      if (id != null && attrvalue.toLowerCase().contains(id.toLowerCase())) {

                        matchingAppId = id;

                        log.debug("Before Provisioning Rule : singleEntitlement : matchingAppId is : " + matchingAppId);

                        break;

                      }

                    }



                    if (matchingAppId != null) {

                      log.debug("Before Provisioning Rule : singleEntitlement : Entered the matchingAppId if condition");



                      String nativeId = accountRequest.getNativeIdentity();

                      log.debug("Before Provisioning Rule : singleEntitlement : nativeId is : " + nativeId);

                      //Get user account

                      Account account = idn.getAccountByNativeIdentity(application.getName(), nativeId);

                      log.debug("Before Provisioning Rule : singleEntitlement : account is : " + account);



                      //Get entitlements associated with account

                      List ents = (List)(idn.getRawAccountAttribute(account, ENT_ATTR_NAME));

                      if (ents != null) {

                        log.debug("Before Provisioning Rule : singleEntitlement : Entered the ents if condition");

                        for (Object entObj: ents) {

                          // Check if entitlement name contains the App IDs

                          String ent = entObj.toString();

                          log.debug("Before Provisioning Rule : singleEntitlement : ent is : " + ent);

                          if (ent != null && ent.toLowerCase().contains(matchingAppId.toLowerCase())) {

                            existingmatchingEntitlement = ent;

                            log.debug("Before Provisioning Rule : singleEntitlement : existingmatchingEntitlement is : " + existingmatchingEntitlement);

                            break;

                          }

                        }

                        if (existingmatchingEntitlement != null) {

                        log.debug("Before Provisioning Rule : singleEntitlement : Entered the account request add section of code");

                        log.debug("Before Provisioning Rule : singleEntitlement : checking value accountRequest.getNativeIdentity() = " + accountRequest.getNativeIdentity());

                        log.debug("Before Provisioning Rule : singleEntitlement : checking value existingmatchingEntitlement = " + existingmatchingEntitlement);

                        log.debug("Before Provisioning Rule : singleEntitlement : checking value attributeValue = " + attributeValue);

                        log.debug("Before Provisioning Rule : singleEntitlement : checking value attrValue = " + attrvalue);

                       

                        if (existingmatchingEntitlement != null && attrvalue != null && accountRequest != null){

                        accountRequest.add(new AttributeRequest(ENT_ATTR_NAME, ProvisioningPlan.Operation.Remove, existingmatchingEntitlement));

                        

                            log.debug("Before Provisioning Rule : singleEntitlement : Final accountRequest is: " + accountRequest);

                              }

                         log.debug("Before Provisioning Rule : singleEntitlement : End of code1");

                        }

                      }

                    }

                  }

                }

              }

            }

          }

        }

      }

    }

  }
}


I think you are missing one } at the end of your rule. Can you check?

@iamnithesh , that image got pasted before the closing bracket. The bracket is there ( i have edited the post now, sorry for the confusion). The rule validator is not throwing any error. Infact a correct plan is also getting generated. But the access request is getting failed with an unknown rule error. When I am removing the rule from the source then the provisioning is working absolutely fine.

Has the rule been deployed and are you referring to the rule in source config with correct id?

yes, the rule is patched to the source and if you see the error screenshot, it has the rule name mentioned in it.

1 Like

Can you share the complete code (XML) ?

I am trying to understand if your plan works. My understanding of the before provisioning rule is that its operation is strictly in the cloud and not the target source and its more of a read only operation rather than an action rule. This lines up with ISC golden rule that there should be no direct amendments to the identity profile value unless triggered by a source.
You are trying to remove entitlement (in the target or in ISC?)
I do understand what you are trying to achieve which is a conditional access request, if you are in entitlement A then you cannot get entitlement B unless you are removed from entitlement A. Which brings up another question– if the removal from entitlement A is via code where is the governance and could there be a functional impact to the user or the organization?