Advanced 18 min read

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.

APEX

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.

APEX

with sharing, inherited sharing, and User-Mode Operations Quiz

1. What does without sharing do?

2. What does inherited sharing mean for a class?

3. What does AccessLevel.USER_MODE enforce that with sharing alone does not?

4. Should without sharing be a common default choice?

5. Why is inherited sharing particularly useful for reusable utility classes?

Log in to submit the quiz and save your score.

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.