Jennifer Lee and Tom Bassett in a new episode of "How I Solved It"

How I Solved It: Selectively Control Record Access from Account Fields

By

Welcome to another post in the “How I Solved It” series. In this series, we do a deep dive into a specific business problem and share how one #AwesomeAdmin chose to solve it. Once you learn how they solved their specific problem, you’ll be inspired to try their solution yourself! Watch how Tom Bassett uses the power of point-and-click tools—Flow, Restriction Rules, and Experience Cloud—to selectively control record access from Account fields. Read more details in the post below.

Key business problem

As a Salesforce Admin, when you’re defining your data model, you have a number of important things to consider. Do you need to use a master-detail or lookup relationship on your custom object? Which organization-wide default sharing setting should you apply? Should you grant access using profiles or permission sets? What about when you have customer/partner users, for which Salesforce users want to toggle access on and off from the account?

Background

For the purposes of this blog, terms have been changed to protect client confidentiality.

My client is developing an Experience site for high-tier partners from different regions, with a number of different features.

Salesforce Schema showing the Account object, related to Promotion Participant and Partner Performance objects; Promotion is also related to Promotion Participant object.

They use profiles for page layout assignments, and for everything else they use permission sets, which is largely considered a best practice.

It’s not scalable to manage all the different permission sets, as the business logic for this is on a case-by-case basis. They use a permission set group by region, meaning each user gets access to all features by default via the group.

Permission set group for DE Region including Baseline Access, Case Access, Performance Access, and Promotion Access permission sets

Permission set group for US Region including Baseline Access, Case Access, and Performance Access permission sets

However, not all users should have access to all features, and this should be controlled by fields at the Account level by a Salesforce user with standard user permissions (not an admin).

How I solved it

1. Lay the foundations

This first step involved some admin “essentials” to ensure the custom object, custom fields, page layouts, and permissions for internal users were set up.

For starters, I set up an object for Promotion so that I could store details of our amazing offers that our partners wanted to participate in. This included creating the custom fields defined by our business teams, creating page layouts, and assigning permissions for Salesforce users to be able to access.

Next up, Promotion Participants was born as an object itself with a master-detail relationship to the Account and Promotion objects, making it a junction object to store the details of a partner’s participation in a promotion. This covered the fields, page layouts, and permissions for in-house Salesforce users. This way, I could build all-important roll-up summaries on the Promotion level so we could monitor performance using clicks-not-code tools.

Partner Performance was the last object to be formed with a lookup relationship to an Account that I’ll use later in our sharing set! Again, I needed to add some fields here that the business teams had asked for, spruce up the page layout, and make sure Salesforce users were able to create, read, edit, and delete records.

On the Account level, I created picklist fields for Can Access Promotions? and Can Access Partner Performance? so that Salesforce users could control these values. These fields have Yes/No values to make things clear for users.

To match at the User level, I created two fields—Hide Performance Tab and Hide Promotion Tab—to map these values to.

To bring all of this together, I created a Lightning app (Partner Management) to hold the Account, Contact, Promotions, Promotion Participants, Partner Performance, Reports, and Dashboards tabs.

I created a Partner Hub profile for our Experience site by cloning the standard profile. The Partner Hub itself was then birthed with that profile as users were granted access to the Experience Cloud site.

For each region and feature, I created a permission set and placed it in a designated permission set group per region.

At this point, I also created a number of test users and test records within the sandbox I was working in so that I could test my progress along the way.

2. Create the pages

Within Experience Builder, I created my pages. These act as landing pages for each object and can be served up to users on the navigation menu. It was important these were created as standard pages so that they weren’t directly tied to object permissions or tab access. This is because the permission set group would automatically give access to the tabs.

Experience Builder showing the page selection menu when creating a new page, with options for Standard Page and Object Pages]

Once these were done, I added in a list view of Promotion, Promotion Participant, and Partner Performance records to each respectively, then I got to work creating my audiences. These are used to show or hide elements or pages in a site and can be based on domain, location, custom permissions, profile, record, or User fields as well as other audiences.

As an #AwesomeAdmin, I never underestimate the power of strong naming convention, and so I went with Performance User and Promotions User.

Once the audiences were done, I set my pages to only be visible to select audiences.

  • Promotions (Promotion object) and My Promotions (Promotion Participant) were assigned to the Promotions User audience.
  • My Performance was assigned to the Performance User audience.

Experience Builder showing the Promotions User audience

Experience Builder showing the Promotions User audience assigned to the Promotions page

3. Let’s talk about sharing

The Promotions sharing settings were set to be private for external users. As a result, I used a sharing rule with ‘All Partner’ users to open up access.

Sharing rule that shares Promotion records with All Partner Users

Promotion Participant had a master-detail relationship to the Account and Promotion objects, so access was inherited from those parent records.

But what about Partner Performance, you say? No worries! We’ll create a sharing set for this, assign it to the Partner Hub profile, and include this with access to the Account object too.

Salesforce Setup showing the sharing set that shares Account and Partner Performance records with Partners

4. Modify restriction rules

Now that I had opened up access, I needed to dial this back!

We want users to be able to turn access on and off using Account fields, which will in turn update the mapped fields on the User a little like this:

If Account Field

Equals

Then User

Equals


Can Access Promotions?

Yes


Hide Promotion Tab

No


Can Access Promotions?

No


Hide Promotion Tab

Yes

Can Access Partner Performance?

Yes


Hide Performance Tab

Yes

Can Access Partner Performance?

No


Hide Performance Tab

No

As a restriction rule can only be based on user criteria or custom permissions (and only supports certain fields), I’ve already set the groundwork for this.

Let’s start with our rule for the Promotion object. To recap, we need to hide Promotion records for those where Hide Promotion Tab = Yes.

I set a clear name for the rule, added a description, made sure it’s active, and filled in the user criteria to only apply to users where Hide Promotion Tab = Yes. Under record criteria, I deliberately set a condition that wouldn’t be met, as the Name field was an auto number field.

Promotion restriction rule set up so that records are hidden for certain users

Next, I created the equivalent rules for Promotion Participants and Partner Performance objects.

Promotion Participant restriction rule that hides records from ineligible users

Restriction rule that hides Partner Performance records from certain users

5. Build a flow

Using the power of Salesforce automation, I built a record-triggered flow on the Account object so that whenever my special fields were updated, the user values were updated too. This way, the logic for the restriction rules was maintained in real time.

I built the same thing on the User object so when a user was created, the fields were set based on the values on the account at that point in time.

The flow to maintain the field values on the User record level

6. Add a Quick Action

On the Account object, I added the ‘preference’ fields into a Quick Action so that internal users could update these at the click of a button. I added this to the page layout so that the users within Salesforce could then use this to manage preferences.

6. Add a Quick Action On the Account object, I added the 'preference’ fields into a Quick Action so that internal users could update these at the click of a button. I added this to the page layout so that the users within Salesforce could then use this to manage preferences.

On the Account object, I added the ‘preference’ fields into a Quick Action so that internal users could update these at the click of a button. I added this to the page layout so that the users within Salesforce could then use this to manage preferences.

7. Test, test, test!

Like with all changes in Salesforce, the last step is to test thoroughly.

This involves testing for each user combination to make sure the expected results are the actual results, that the Account and User fields are mapped to each other, and, most importantly, that users can only see the records they should.

A good way to test this is by using Global Search, as this will show records you have access to. The landing pages for each feature are controlled by audiences, so, should the criteria not be met, they would not have been visible—which makes it impossible to test record access that way.

When testing as a user who has no access to Promotions, those records are indeed hidden from Global Search.

When testing as a user who has no access to Promotions, those records are indeed hidden from Global Search.

8. Install Map Contacts to Experience Cloud users

As the creator of this app, I like to practice what I preach and use this for my own purposes where possible. This allows me to easily see on the Contact level if there was an active partner community.

Contact Compact layout sharing the Active Experience Cloud User, their status, and if the email addresses did not match between the Contact and the User

I created a list view to track my active partner users, which was shared with all Salesforce users for ease.

A list view filtered by User Active = TRUE to only show my active Partner Users

You can get the app here on the AppExchange.

Business results

The foundations were truly set for more regions and features to be rolled out in the future.

Using the power of point-and-click, my client can now self-manage the setup going forward—and this could easily scale to include more features as the Partner Hub expands.

As no code is involved, they are able to act rapidly to changes in an agile manner and achieve their goals.

Do try this at home

In this use case, I had a very specific request for users to be able to manage system permissions for partner users from account fields.

Using the power of Flow, restriction rules, and permission sets, I was able to meet the business requirements and solve this using clicks, not code.

Be sure to use this example to inspire your solutions to similar business challenges, and check out the resources below to get started.

Resources

Want to see more good stuff? Subscribe to our channel!

SUBSCRIBE TODAY