Skip to content

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.

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.

So before anyone writes a share, walk the sets from chapter 5, in order:

  1. Do the defaults and the hierarchy do it? Org-wide defaults, ownership, queues, the role hierarchy (chapter 6).
  2. 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.
  3. Do the hand tools do it? Manual shares, teams, territories (chapter 9).
  4. Does the data model already do it? Controlled by Parent, and implicit sharing (chapter 6, and chapter 10).
  5. Can code set a field, and a rule share on it? The hybrid, below.
  6. Only then: code or a flow writes the shares.
The questions before code The questions before code. One: do the defaults and the role hierarchy give the access? Two: does a criteria-based or owner-based rule? Three: manual shares, teams or territories? Four: does the data model already share it, through Controlled by Parent or implicit sharing? Five: can code set a field, and a rule share on that field? Six, the last: code or a flow writes the share records. Footnote: use native sharing everywhere you can; go to code only when there's no other way. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.58.0", "built": "2026-11-03", "id": "DGM-SVA-PS-01", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "flow/sequence 0.1.0", "theme": "stevetecharc 1.4.0"} Defaults and the hierarchy chapter 6 Org-wide defaults, ownership, queues, roles. A sharing rule chapters 7 and 8 Criteria-based or owner-based. Count the buckets. Manual shares, teams, territories chapter 9 Shared by hand, or by membership. The data model chapters 6 and 10 Controlled by Parent, and implicit sharing. Code sets a field, a rule shares the hybrid Code keeps a field right; the rule does the sharing. Code or a flow writes the shares the last tool Only when nothing above can see the decision. 1 2 3 4 5 6 ASK IN THIS ORDER Use native sharing everywhere you can. Go to code only when there's no other way. HOW TO READ IT 1 the order a step the step that matters most what comes next © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

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.

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.

Code shares, or code sets a field and a rule shares Two ways to share a US opportunity that contains a hardware item. Code shares: code writes a share for each opportunity, and it must handle new line items, owner changes, new users in the hardware branch, and recalculation; the shares can only be seen by a query. Code sets a field, a rule shares: code or a flow sets Has Hardware when a line item is added; a criteria-based rule shares US opportunities with Has Hardware to the VP of Hardware role and subordinates; Salesforce keeps the shares right, and the rule is visible in Sharing Settings. Footnote: code that keeps a field right is easier to live with than code that keeps shares right. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.58.0", "built": "2026-11-03", "id": "DGM-SVA-PS-02", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "comparison 0.5.0", "theme": "stevetecharc 1.4.0"} Code shares a share per opportunity Writes a share for each record Handles new items, owners, users Recalculates when the logic changes Seen only by a query Code sets a field, a rule shares Has Hardware, then a criteria rule Code or a flow sets Has Hardware The rule shares to the hardware VP's branch Salesforce keeps the shares right Seen in Sharing Settings Code that keeps a field right is easier to live with than code that keeps shares right. © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

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.

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.

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).
  • 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.