Creating Custom Record Sharing Logic Using Salesforce Flow

Creating Custom Record Sharing Logic Using Salesforce Flow

Big Idea or Enduring Question:

  • Sharing records automatically without sharing rules or role hierarchy
  • Using Apex Managed Sharing declaratively

Objectives:

After reading this blog post, the reader will be able to:

  • Create declarative automation to automatically share a record
  • Share a record without sharing rules or role hierarchy
  • Create a Record-Triggered Flow to insert a row in Share Table

Business Use Case

Brenda David is working as a System administrator at Universal Containers (UC). Currently, she is working on a project that is implementing audit management for Assets. For this she has created a custom object Audit (OWD: – private) and few custom fields as shown in the following screenshot:

Part 16.1

The business requirement

  • as soon as Auditor__c (Lookup to User object) field gets populated, auto-share the Audit record (Grant edit access) with the auditor.

Automation Champion Approach (I-do):

Salesforce allows you to control data access at many different levels (object-level, record-level, and field-level). We will focus on methods for controlling access to data at the record level. 

In most scenarios, you can use out-of-the-box sharing settings to grant record access, but there are few use cases where you have to write an Apex Managed Sharing rule to share the records with users or groups. 

Apex Managed Sharing allows you to use Apex code to build sophisticated and dynamic sharing settings that aren’t otherwise possible. In this article, ‘ll use After-save Record-Triggered Flow to solve the business requirement. Check out this article to understand why we are using after-save record-triggered flow for this scenario.

Before proceeding, make sure you understand the sharing table in Salesforce. All objects that have a default sharing setting of either Private or Public Read Only. These objects also have a related Share object that is similar to an access control list (ACL) found on other platforms. 

All Share objects for custom objects are named as CustomObject__Share, where CustomObject__c is the name of the related custom object. A shared object includes records supporting all three types of sharing (Force.com managed sharing, User managed sharing, and Apex managed sharing). 

The Share object contains the following fields:

Field Name Details
ParentId The Id of the record being shared. This field cannot be updated.
UserOrGroupId The Id of the User to whom you are granting access.
AccessLevel The level of access that the specified User or Group has been granted.
RowCause (aka Sharing Reasons) The reason why the user or group is being granted access.

Before discussing the solution, let me show you a diagram of a Process Flow at a high level. Please spend a few minutes going through the following Flow diagram and understand it.

Let’s begin building this automation process.

Guided Practice (We-do):

There are 3 steps to solve Brenda’s business requirement using After-save Record-Triggered Flow. We must:

  1. Create a custom object with fields
  2. Create apex sharing reason 
  3. Salesforce flow
    1. Define flow properties for record-triggered flow
    2. Create a record variable (varR_AuditShare) to store Audit__Share
    3. Add a decision element to check if auditor is populated or not 
    4. Add an assignment element to populate record variable (varR_AuditShare)
    5. Add a create records element  to share the audit record with the auditor

Step 1: Create a Custom Object Audit and Fields 

    1. Click Setup.
    2. In the Object Manager, click Create | Custom Object.
    3. Now create a custom object Audit and fields as shown in the screenshot below: 
    4. Click Save.

Part 16.1

Step 2: Create Apex Sharing Reason

First, we will create an Apex Sharing Reason. Each Apex sharing reason has a Label and a Name. The Label value is displayed in the Reason column when viewing the sharing for a record in the user interface. This allows users and administrators to understand the source of the sharing. 

  1. Click Setup.
  2. In the Object Manager, type Audit.
  3. Select Apex Sharing Reasons, then click New.
  4. Enter Reason Label and press the Tab key the Reason Name will populate. 
  5. Click Save.

Step 3.1: Salesforce Flow – Define Flow Properties 

  1. Click Setup.
  2. In the Quick Find box, type Flows.
  3. Select Flows then click on the New Flow.
  4. Select the Record-Triggered Flow option and click on Next and configure the flow as follows: 
    1. How do you want to start building: Freeform
    2. Object: Audit
    3. Trigger the Flow When: A record is created or updated 
    4. Set Entry Criteria
      1. Condition Requirements: None
    5. Optimize the Flow For: Action and Related Records 
  5. Click Done.

Step 3.2: Salesforce Flow – Create a Record Variable to Store Audit__Share 

  1. Under Toolbox, select Manager, then click New Resource to store the audit__share mapping detail. 
  2. Input the following information: 
    1. Resource Type: Variable
    2. API Name: varR_AuditShare
    3. Data Type: Record
    4. Object: Audit__Share
    5. Check Available for Input
    6. Check Available for Output
  3. Click Done.

Step 3.3: Salesforce Flow – Using Decision Element to Check if Auditor field Is Populated or Not 

Now we will use the Decision element to check the Auditor__c from Audit object to find if it is populated by user or not. 

  1. Under Toolbox, select Element
  2. Drag-and-drop Decision element onto the Flow designer. 
  3. Enter a name in the Label field; the API Name will auto-populate.
  4. Under Outcome Details, enter the Label the API Name will auto-populate.
  5. Condition Requirements to Execute OutcomeAll Conditions Are Met (AND)
    1. Row 1:
      1. Resource: {!$Record.Auditor__c}
      2. Operator: Is Null 
      3. Value: {!$GlobalConstant.False}
    2. Add Field
    3. Row 2:
      1. Resource: {!$Record.Auditor__c}
      2. Operator: Is Changed 
      3. Value: {!$GlobalConstant.True
  6. Click Done.

Step 3.4: Salesforce Flow – Adding an Assignment Element to Populate Audit__Share Record Variable 

The next step is to populate the record variable Audit__share to share the audit record with Auditor.

  1. Under Toolbox, select Assignment. Drag and drop Assignment onto the canvas. 
  2. Input the following information:
    1. Enter Label the API Name will auto-populate.
    2. Row 1:
      1. Field: {!varR_AuditShare.AccessLevel}
      2. Operator: Equals
      3. Value: Edit
    3. Click Add Row
    4. Row 2:
      1. Field: {!varR_AuditShare.ParentId}
      2. Operator: Equals
      3. Value: {!$Record.Id}
    5. Click Add Row
    6. Row 3:
      1. Field: {!varR_AuditShare.UserOrGroupId}
      2. Operator: Equals
      3. Value: {!$Record.Auditor__c}
    7. Click Add Row
    8. Row 4:
      1. Field: {!varR_AuditShare.RowCause}
      2. Operator: Equals
      3. Value: Share_record_with_Auditor__c
  3. Click Done.

Step 3.5: Salesforce Flow – Adding a Create Records Element to Share the Audit Record with Auditor 

  1. Under Toolbox, select Element
  2. Drag-and-drop the Create Records element onto the Flow designer. 
  3. Enter a name in the Label field- the API Name will auto-populate.
  4. For How Many Records to Create select One.
  5. Map Record Collection: {!varR_AuditShare}
  6. Click Done.

In the end, Brenda’s Flow will look like the following screenshot (I turned on Auto-Layout) for this flow:

Once everything looks good, perform the steps below: 

  1. Click Save.
  2. Enter Flow Label the API Name will auto-populate.
  3. Click Show Advanced.
  4. API Version for Running the Flow: 53
  5. Interview Label: Share record with Auditor {!$Flow.CurrentDateTime}
  6. Click Save

Almost there! Once everything looks good, click the Activate button.

Proof of Concept

Now onwards, When a business user creates an audit record with an Auditor, then Salesforce Flow will automatically trigger which will share the audit record with the auditor. You will have to do some of this testing in Your Org.

  1. Currently, the audit for Dell PowerEdge Tower Servers FY21 doesn’t have an auditor, as shown in the following screenshot:
  2. Now update the audit record with the valid auditor:
  3.  To verify the outcome, click on the sharing button, it will open a detail as shown in the following screenshot:

Independent Practice (You-do):

  • In a sandbox or dev/Trailhead org, create a quick custom object with a look-up to the Opportunity record
    • Include a User look-up
  • Create a sharing rule as outlined above

Formative Assessment:

I want to hear from you!  

What did you learn from this post, is it relevant to you, and how will you modify the concepts taught in the post for your own business processes?  

Make a post and tag me on Twitter @automationchamp using #AutomationChampionFlow.

Have feedback, suggestions for posts, or need more information about Salesforce online training offered by me? Say hello, and leave a message!

3 thoughts on “Creating Custom Record Sharing Logic Using Salesforce Flow

  1. Hi!
    This is great and very neatly explained!

    One question: what should be the best approach for revoking access to the auditor once the field “Auditor” is left blank or the user is replaced?

    I’m having issues with after delete flows (for records) and was wondering how to achieve it in this case.

    Thanks for the amazing information shared!

    1. Glad to help. 🙂

      How about creating a record-triggered flow when the Auditor field change, then using a Delete Records element to revoke access? Can you explain the issue you are facing with this approach?

  2. Hi Rakesh,

    Awesome process. One question I have is what can be done when trying to replace sharing settings with this process when it comes to old records? If we delete a Sharing Rule and replace it with this flow, then logically, a user wouldn’t be able to even have read access for records they used to be able to access because they wouldn’t have been edited yet to launch the flow. Is there a way around that other than doing a “blank” update of all the records for the object in the org?

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.