Advertisement

Leaderboard — 728×90 desktop / 320×50 mobile
Security & Sharing

Salesforce Security Model — The Complete Deep Dive

3 June 2025 · 16 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 Queues specifically, Summer ‘26 introduces a new Grant Access Using Hierarchies setting. Previously, records shared with a queue were automatically shared with the queue members’ superiors in the role hierarchy. You can now disable this behaviour — useful for queues that handle sensitive work items that managers should not automatically see.

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 reversal of
Apex sharing defaults. Classes without an explicit `with sharing` or
`without sharing` declaration now default to `with sharing` in API v67.0.
This means SOQL queries in undeclared classes will enforce the running
user's sharing rules automatically.

For existing code, this means: before upgrading any class to API v67.0,
audit every class for missing sharing declarations. Add explicit
declarations to every class. Test under restricted user profiles. Code
that previously returned all records regardless of sharing may now
return a subset.

## 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 the old `without sharing` default for security-sensitive queries

Test your knowledge — Security & Sharing

10 questions · Basic to Advanced

0 / 10 correct

Advertisement

In-content — 300×250