with sharing, inherited sharing, and User-Mode Operations
By the end of this lesson, you'll be able to:
- Distinguish with sharing, without sharing, and inherited sharing Apex class modifiers
- Explain why inherited sharing matters for reusable utility classes
- Use User-Mode database operations for the strongest, most deliberate default
Prerequisites: "The Salesforce Security Model: CRUD, FLS, and Sharing"
with sharing vs. without sharing
public with sharing class AccountController {
// record-level sharing rules ARE enforced for queries/DML in this class
}
public without sharing class AdminUtility {
// record-level sharing rules are deliberately bypassed here
}
with sharing enforces the running user's record-level sharing rules for queries and DML inside that class. without sharing deliberately bypasses them — a choice that should be rare, explicit, and well-justified (e.g. a controller that genuinely needs to check something outside the user's normal visibility), never a default reached for out of convenience.
inherited sharing
public inherited sharing class RecordFormatter {
// runs with sharing enforced if its CALLER does; without, if the caller doesn't
}
A class with no sharing keyword has genuinely ambiguous behavior — it depends on context in ways that are easy to get wrong. inherited sharing makes this explicit: the class runs in whatever sharing mode its caller is running in. This matters most for reusable utility classes that might be called from both with sharing and without sharing contexts — the utility shouldn't silently override its caller's security posture either way.
User-Mode Operations
List<Account> accounts = Database.query(
'SELECT Id, Name FROM Account',
AccessLevel.USER_MODE
);
Database.insert(newAccount, AccessLevel.USER_MODE);
Passing AccessLevel.USER_MODE to a Database method enforces CRUD, FLS, and sharing together for that single operation — a stronger, more complete guarantee than with sharing alone, which only governs record-level sharing, not field-level security. This is now the recommended default for Apex exposed to LWC, since it matches the same full enforcement LDS already provides automatically (Lesson 1).
Exercise
Convert this query to use AccessLevel.USER_MODE for full CRUD/FLS/sharing enforcement.
Show hint
Use Database.query with the AccessLevel parameter.
Exercise
Challenge: explain, as a comment, why inherited sharing is preferable to leaving a reusable utility class with no sharing keyword at all.
Show hint
Think about what "no keyword" actually means for behavior.
with sharing, inherited sharing, and User-Mode Operations Quiz
My Notes
Log in to keep private notes on this lesson.
Questions about this lesson
No questions yet — be the first to ask.
Log in to ask a question about this lesson.
Summary
Sharing modifiers control record-level access at the class level, while User-Mode database operations offer a stronger, single-operation guarantee covering CRUD, FLS, and sharing together — Apex exposed to LWC should almost always default toward respecting the running user's real access.