Security & Sharing

Salesforce Security Model — The Complete Deep Dive

By Rishabh Panwar · 5 min read · Advanced

The Salesforce security model is not a single switch — it is a layered system of access controls that work together to ensure users see exactly the records and fields they are supposed to, and nothing more. Understanding each layer and how they interact is fundamental to every implementation, regardless of cloud or industry.

The four layers of Salesforce security

Salesforce security operates across four distinct dimensions. Each one answers a different question about access.

Organisation level — who can log into the org? Managed through IP restrictions, login hours, two-factor authentication and My Domain policies.

Object level — which objects can a user see, create, edit or delete? Managed through Profiles and Permission Sets.

Record level — which specific records within an accessible object can a user see? Managed through OWD, the role hierarchy, sharing rules, manual sharing and Apex managed sharing.

Field level — which fields within an accessible record can a user see or edit? Managed through Field-Level Security on Profiles and Permission Sets.

Getting any one of these wrong produces either a security vulnerability (too much access) or a broken user experience (too little access). The layers interact — you cannot fix record-level exposure with field-level restrictions.

Org-Wide Defaults — the security foundation

OWD is the single most important security decision in any Salesforce implementation. It sets the most restrictive possible access for each object — the floor that no other setting can go below.

The three standard settings for most objects are Private, Public Read Only and Public Read/Write. Private means users can only see records they own. Public Read Only means all users can see all records but only owners can edit. Public Read/Write means all users can view and edit all records.

The critical rule: all other sharing mechanisms can only open access beyond OWD, never restrict it. If Account is set to Public Read/Write, there is no sharing rule or profile setting that prevents a user from seeing another user’s Account records. This is why getting OWD right before go-live matters enormously — changing OWD on a large object with millions of records can trigger a sharing recalculation that takes hours.

Profiles and Permission Sets

Profiles control object-level and field-level access. Every user must have exactly one Profile. Permission Sets are additive — they can only grant access that the Profile has not already granted. A user can have many Permission Sets.

The best practice in mature orgs is a minimum-access Profile (often called a base Profile or Minimum Access Profile) combined with Permission Sets that grant specific access for specific roles. This avoids the anti-pattern of maintaining dozens of nearly-identical profiles.

In Summer ‘26 the new Field Access tab in Object Manager shows all field permissions across all profiles and permission sets in one view — a significant improvement over the previous approach of opening each profile individually.

The role hierarchy

The role hierarchy grants record access upwards. A user in a higher role can see all records owned by users below them in the hierarchy. This implicit sharing requires no configuration beyond setting up the hierarchy.

For custom objects, the Grant Access Using Hierarchies checkbox on the org-wide default switches this off. Standard objects always grant access through the hierarchy, so a sensitive standard-object record needs a Private OWD plus deliberately narrow sharing rules rather than a hierarchy setting.

Sharing rules

Sharing rules extend access to groups of users beyond what OWD allows. Ownership-based rules share records owned by one public group or role with another. Criteria-based rules share records matching specific field conditions — for example, sharing all Opportunities with Stage = Closed Won with the Finance team.

Every sharing rule requires a From group and a To group, and specifies whether the grant is Read Only or Read/Write. There is no way to create a sharing rule that restricts access.

Apex managed sharing

When declarative sharing rules cannot express the required logic, Apex managed sharing fills the gap. You insert records into the Share object for the relevant SObject — AccountShare, OpportunityShare or MyObject__Share for custom objects.


// Grant Read access to an Account for a specific user
AccountShare share = new AccountShare();
share.AccountId     = accountId;
share.UserOrGroupId = userId;
share.AccountAccessLevel  = 'Read';
share.OpportunityAccessLevel = 'None';
share.CaseAccessLevel = 'None';
share.RowCause = Schema.AccountShare.RowCause.Manual;
insert share;

Use a custom Apex sharing reason (rather than Manual) when your sharing logic should survive profile-level sharing recalculations and be distinguishable from user-initiated manual shares.

Summer ‘26 security changes (API v67.0)

The most impactful Summer ‘26 change for security is the Apex sharing default. From API v67.0 a class with no with sharing / without sharing / inherited sharing keyword runs with sharing, so its SOQL enforces the running user’s org-wide defaults, sharing rules and manual shares.

The common belief that “no keyword used to mean without sharing” is only partly right. On v66.0 and earlier the default depended on how the transaction started: Aura controllers and @AuraEnabled methods called from LWC already ran with sharing; Visualforce controllers, Apex REST services, asynchronous classes and every other entry point ran without sharing. A class with no keyword also takes the sharing mode of the class that called it. So the classes that change behaviour on a version bump are the second group — REST services, batch and queueable classes, invocable methods and Visualforce controllers — not LWC controllers.

Two other v67.0 changes land at the same time: database operations run in user mode by default (object and field permissions enforced), and WITH SECURITY_ENFORCED no longer compiles. The Apex security guide covers all three; the v67 migration scenario covers what breaks and how to fix it.

Before raising any class to API v67.0, add an explicit sharing keyword, decide each query’s access mode deliberately, and run the tests as a restricted user. Code that returned every record may now return a subset — silently.

The security review checklist

Before go-live, verify these for every object in scope:

  • OWD set to the most restrictive appropriate setting
  • Role hierarchy reflects the real reporting structure
  • Sharing rules cover all legitimate cross-team access needs
  • Profiles grant minimum necessary object permissions
  • Permission Sets cover role-specific access beyond the base profile
  • FLS restricts sensitive fields from users who should not see them
  • Apex classes have explicit sharing declarations
  • No class relies on an omitted sharing keyword; every class states with, without or inherited sharing

Test your knowledge — Security & Sharing

10 questions · Basic to Advanced

0 / 10 correct

Frequently asked questions

What is the Salesforce security model?

The Salesforce security model is a layered access control system comprising Org-Wide Defaults, role hierarchy, sharing rules, profiles, permission sets, and field-level security. Each layer controls a different dimension of access — from which records a user can see to which fields they can edit.

What are Org-Wide Defaults (OWD) in Salesforce?

Org-Wide Defaults set the baseline level of record access across the entire org. Every other sharing mechanism — sharing rules, role hierarchy, Apex managed sharing — can only open access beyond OWD, never restrict it further. Getting OWD right before go-live is critical because changing it on large objects triggers a sharing recalculation that can take hours.

What is the difference between Profiles and Permission Sets?

Every user has exactly one Profile, which sets the baseline of object and field access. Permission Sets are additive — they can only grant additional permissions on top of the Profile. A user can have many Permission Sets, enabling role-specific access without maintaining separate profiles for every combination.

What is Field-Level Security (FLS) and where is it configured?

Field-Level Security controls whether a user can view or edit a specific field on an object. It is configured on Profiles and Permission Sets. Summer '26 added a Field Access tab in Object Manager that shows all field permissions across profiles and permission sets in a single view.

What is Apex Managed Sharing and when should I use it?

Apex Managed Sharing grants record access programmatically by inserting rows into an object's Share object (such as AccountShare or MyObject__Share). Use it when declarative sharing rules cannot express the required logic — for example, dynamically sharing a record based on related record conditions.

What did the Summer '26 API v67.0 change about Apex sharing defaults?

In API v67.0 a class with no sharing keyword runs with sharing. Before v67.0 the default depended on the entry point: Aura and LWC controllers already ran with sharing, while Visualforce controllers, Apex REST services, asynchronous classes and other entry points ran without sharing. Code in those second-group classes that relied on seeing every record may return fewer rows after upgrading.

What is the role hierarchy in Salesforce sharing?

The role hierarchy grants record access upward — a user in a higher role can see all records owned by users below them, without any explicit sharing rule. For custom objects, the Grant Access Using Hierarchies checkbox on the org-wide default turns this off; standard objects always grant access through the hierarchy.