Before Provisioning Rule Support for Salesforce SaaS Connector to Update Profile During Revoke Access

Hello Developers,

Hope you are doing good!

Can we implement a Before Provisioning Rule for the Salesforce SaaS connector?

As per the client’s requirement, during the revoke access request, we need to remove the Profile entitlement from the Salesforce account. Since the Profile is a mandatory attribute in Salesforce, we want to replace the existing profile with the Standard User profile before removing the entitlement.

Could anyone please confirm whether we can implement Before Provisioning Rule for the Salesforce SaaS connector & write this logic in a Before Provisioning Rule?

Yes, you can use a BP Rule to work with the Salesforce SaaS connector. This would be a cloud Before Provisioning Rule, not a connector-level rule.

For your use case, instead of removing the Profile, the rule catches that remove action and swaps it to “Standard User.” So Salesforce always has a valid Profile on the account, and the revoke goes through without errors.

Since this is a cloud rule, SailPoint needs to review and approve it before it can be deployed. You will submit it through Expert Services as part of the rule review process.

Yes, you can create a Before Provisioning Rule, because SailPoint’s Before Provisioning Rule is meant to modify the provisioning plan before it is sent out. However, it is a SaaS Connector, so do check for Customizers as well if that can be handled using Customizers.

This is absolutely doable with a Before Provisioning rule. As mentioned, I would highly recommend to see if a customizer may offer the same functionality without having to go through the Cloud Rule deployment process. If you go through a Before Provisioning rule, here is a sample on how I’ve accomplished this before:

import java.util.LinkedList;

import java.util.List;

import org.apache.commons.lang.StringUtils;

import sailpoint.object.ProvisioningPlan;

import sailpoint.object.ProvisioningPlan.AccountRequest;

import sailpoint.object.ProvisioningPlan.AccountRequest.Operation;

import sailpoint.object.ProvisioningPlan.AttributeRequest;

import sailpoint.object.Identity;




/* 
Store the profileId under the "connectorAttributes.defaultProfileId" in the source JSON.
*/
String DEFAULT_PROFILE = (String) application.getAttributeValue("defaultProfileId"); // Recommended to store environment specific attributes outside of the rule for environment agnostic approach.




if (plan != null) {

    List accountRequests = plan.getAccountRequests();

    Identity identity = plan.getIdentity();

    if (accountRequests != null && identity != null) {

        log.info("Account requests are not null");

        List accreqs = new LinkedList();

        for (AccountRequest accountRequest : accountRequests) {

            AccountRequest.Operation op = accountRequest.getOperation();

            log.info("Account Request Operation: " + op);

            

            if (op != null) {

                if (op.equals(AccountRequest.Operation.Create)) {

                    int profileCount = 0;

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

                        if(attRequest.getName().equals("ProfileId")) {

                            String profileOp = attRequest.getOperation().toString();

                            if (profileOp.equals("Add"))    {

                                profileCount += 10;

                            } else if (profileOp.equals("Remove")) {

                                profileCount += 1;

                            }

                        }

                    }




                    if (profileCount == 0) {

                        List attReqs = new LinkedList();

                        

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

                            if ("ProfileId".equals(attRequest.getName())) {

                                attReqs.add(new AttributeRequest("ProfileId", ProvisioningPlan.Operation.Add, DEFAULT_PROFILE));

                            } else {

                                attReqs.add(attRequest);

                            }

                        }

                        

                        accountRequest.setAttributeRequests(attReqs);

                    }

                } else if (op.equals(AccountRequest.Operation.Modify)) {

                    int profileCount = 0;

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

                        if(attRequest.getName().equals("ProfileId")) {

                            String profileOp = attRequest.getOperation().toString();

                            if (profileOp.equals("Add"))    {

                                profileCount += 10;

                            } else if (profileOp.equals("Remove")) {

                                profileCount += 1;

                            }

                        }

                    }

    

                    if (profileCount < 10) {

                        log.info("The profile is slated for removal. Replace the removal operation with an add of the default.");

                        List attReqs = new LinkedList();

                        

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

                            if ("ProfileId".equals(attRequest.getName())) {

                                log.info("Found the ProfileId Removal in the plan. Replacing for the default: " + DEFAULT_PROFILE);




                                // Replace with default value

                                attReqs.add(new AttributeRequest("ProfileId", ProvisioningPlan.Operation.Add, DEFAULT_PROFILE));

                            } else {

                                attReqs.add(attRequest);

                            }

                        }

                        

                        accountRequest.setAttributeRequests(attReqs);

                    } 

                } 

            }

            accreqs.add(accountRequest);

        }

        plan.setAccountRequests(accreqs);

    }

}

This logic ensures that there are no other profiles being added during the remove operation and ensures that, at minimum, the default is added to the user during the account creation (ex. account creation triggered due to access request).

Hi Shaik! Yes, the Before Provisioning Rule is fully supported for the Salesforce SaaS connector

@bcariaga - After a quick the code. It seems the closing brace is missing for create operation. pls cross check once.