with sharing and without sharing decide whether record-level sharing rules apply to SOQL and DML in that class — independent of CRUD and FLS, which you still enforce separately.In Apex, start from the user story: should this code see the same rows the user sees in the UI? If yes, default to with sharing. If the job truly needs to ignore record visibility (batch, integration, careful admin tooling), isolate without sharing in a small, reviewed class — never sprinkle it everywhere by default.
Three accounts, two reps. Toggle the running user and the class keyword — cards light up when this SOQL would return that row (SELECT Id, Name FROM Account). Teaching model only.
Acme Corp
Alice is owner
Beta LLC
Bob is owner
Gamma Inc
Alice owns; Bob has read via share
Count: 2 rows visible for this combination — compare Alice vs Bob with with sharing, then flip to without sharing and watch all three appear.
Class declaration updates with your keyword
public with sharing class AccountLookup {
public List<Account> visibleRows() {
return [SELECT Id, Name FROM Account];
}
}Scenario → what teams usually pick
Click a scenario — no single answer fits every org; these are conversation starters with architects. Use the cards to prompt design reviews, not as rigid law.
Lightning / Visualforce page
Pattern: with sharing
Honor the running user’s record access — what they see in the UI should match what Apex returns.
Prefer with sharing when…
Consider without sharing when…
with sharing controls record visibility (who owns / shares rows). Profile permission sets and permission set assignments still control object and field access — students learn to combine both, and to use WITH SECURITY_ENFORCED or the stripInaccessible pattern when FLS must be enforced in code.