When Programmatic Sharing Is Justified
Module 1 of 6 in the chapter Programmatic Sharing: Apex and Flow Managed Sharing, chapter 11 of Securing Salesforce: Sharing and Visibility. Each module stands on its own.
The question this module answers: When should sharing be written in code or a flow, and when should it not?
Chapter 5 showed what programmatic sharing really is: you insert a row into the share table yourself, with which record, who, how much and why (Set 5, Programmatic). It used to be called Apex sharing. I call it programmatic sharing now, because flows can do it too.
This chapter is how to do it well. But the first question isn’t how. It’s whether.
The last tool, not the first
Section titled “The last tool, not the first”When I prepare people for the architect review board, I tell them this: we don’t want you to get lazy and Apex-share everything. Some requirements you can solve declaratively. Some may need code. Either way, you have to really think about the right objects, the sharing rules, the ownership and the hierarchy first.
My slide for it has said the same thing for years. Use native Salesforce sharing everywhere you can. Only go to Apex sharing when there are no other alternatives.
Why so strict? Because the moment your code writes a share, you own everything the platform did for you before. When a rule shares a record, Salesforce keeps it right: a new record that matches, an owner change, a new user in the role. When your code shares it, that’s your job:
- The records change. A new record, or a change that means it should now go to someone else.
- The users change. A new user, or a user whose region or skill changes.
- The logic changes. The criteria move, and every existing share has to be recalculated.
- The loads. A million records loaded at once, or the shares for day zero.
And you can’t see the result. Unlike a team, a share written by code has no user interface. It sits in the share table, and you find it with a query.
A student in one of my classes said it well: they’d only used it once or twice, because it’s always a pain, you have to write the trigger and maintain the logic. Another, who had just passed the exam, told the class there were more questions than expected about exactly that: programmatic sharing that went live and didn’t behave, with people seeing records they weren’t supposed to.
The questions before code
Section titled “The questions before code”So before anyone writes a share, walk the sets from chapter 5, in order:
- Do the defaults and the hierarchy do it? Org-wide defaults, ownership, queues, the role hierarchy (chapter 6).
- Does a rule do it? A criteria-based rule on a field on the record, or an owner-based rule on who owns it (chapters 7 and 8). Count the buckets first.
- Do the hand tools do it? Manual shares, teams, territories (chapter 9).
- Does the data model already do it? Controlled by Parent, and implicit sharing (chapter 6, and chapter 10).
- Can code set a field, and a rule share on it? The hybrid, below.
- Only then: code or a flow writes the shares.
When code is justified
Section titled “When code is justified”Rules are powerful, but they have limits. Salesforce allows 300 sharing rules per object, and only up to 50 of them can be criteria-based (How Many Buckets?). And a criteria-based rule can only read fields on the record itself: not a parent, not a related record, not a formula (Criteria-Based Sharing Rules).
So programmatic sharing earns its place when the decision depends on something the declarative tools can’t see:
- Something about a parent or a linked record. Who should see this record depends on another record, not on a field this one holds.
- Something about the user. A skill, a region, a certification on the user, matched to each record. When you get down to that level of detail, programmatic sharing is the best tool you have.
- More buckets than rules allow. Hundreds of values, each its own audience, past the 50.
- The rules live somewhere else. I’ve had clients whose rules of visibility were in another system. That system can feed the share records in through the REST API or the Bulk API. The insert doesn’t have to come from inside Salesforce.
Try the hybrid first
Section titled “Try the hybrid first”Here’s a puzzle I give in board preparation. If a US opportunity contains a hardware item, share it with the VP of hardware and their subordinates.
A criteria-based rule can’t do it. The hardware lives on the opportunity’s line items, not on the opportunity, and a rule can’t read related records. So is this programmatic sharing?
Not necessarily. Every time someone adds a line item, decide whether it’s hardware. A student in that class pointed out that the product family already says it. Then flip a custom field on the opportunity: Has Hardware. In class I said Apex for that; a record-triggered flow can set a field too. Now a criteria-based rule does the sharing: country is US, Has Hardware is true, shared with the VP of Hardware role and subordinates.
Look at what you maintain now. The code keeps one checkbox right. The rule does all the sharing: new opportunities, owner changes, a new person in the hardware branch. Salesforce recalculates it, and anyone can open Sharing Settings and see it.
That’s the trade. Code that keeps a field right is much easier to live with than code that keeps shares right.
The hybrid has limits too. It still uses a bucket from the 50, and it still needs one rule per audience. When the audiences are per user, per skill, per region in the hundreds, you’re back to code. But ask the question first.
Watch your granularity
Section titled “Watch your granularity”One more story from class. A student told us about a client where they’d been tasked with removing shares that code had inserted. Over 100 million of them. It took about a week, and then they had to rethink how the client shared things altogether.
What’s the lesson? Watch your granularity. If code is creating a share for every record for every person, the share table becomes the problem. That’s why module 4 shares with a bucket, a group, instead of a person.
Where code can’t help
Section titled “Where code can’t help”Two places programmatic sharing doesn’t reach, both from chapter 5:
- A detail object in a master-detail relationship has no share object of its own. In Salesforce’s words: “Objects on the detail side of a master-detail relationship don’t have an associated sharing object” (Sharing a Record Using Apex (opens in a new tab), Apex Developer Guide, Winter ‘27, checked 2026-11-07). Its access comes from the master, so share the master.
- High-volume site users have no share table. Customer Community users can’t be given a share row; their tools are sharing sets and share groups (Set 7, Community Licenses; chapter 15).
What an architect decides here
Section titled “What an architect decides here”- For each sharing requirement, which set solves it, walked in order, with the reason each earlier set doesn’t.
- Whether a field set by code or a flow, plus a sharing rule, can do the job instead of code writing shares.
- When code is justified: which decision the declarative tools can’t see, written down.
- How many share rows the design will create, at today’s volume and at three times it.
- Who owns the code’s sharing logic after go-live, since the platform no longer keeps it right.
Beyond the exam: what AI changes. Ask an AI assistant to “make sure the right people see these records,” and it will often write Apex that inserts shares, because that’s the code it has seen most. It works on the first day. Then ask it the same questions you’d ask any developer: does a rule already do this, what happens when the owner changes, what happens when a new user arrives, and how many rows will this write? And agents that act on records inherit whatever your sharing grants, so a share written too widely by code is something an agent can read too. Chapter 20 covers agents.
Explore
Section titled “Explore”- Sharing a Record Using Apex (opens in a new tab), Apex Developer Guide, Winter ‘27 (checked 2026-11-07)
