Skip to main content

SF-0288 · Concept · Medium

What is "With Sharing" and "Without Sharing" in apex?

✓ Verified by Vikas Singhal · Last reviewed 5/17/2026

with sharing and without sharing are Apex class declaration keywords that control whether record-level sharing rules apply when the class executes. A class marked with sharing respects the running user’s sharing — record visibility from OWD, role hierarchy, sharing rules, and manual shares is enforced. A class marked without sharing ignores all of that and operates as if it has access to every record. There’s also inherited sharing, which adopts the calling class’s mode.

The three modes

DeclarationRecord sharing rules enforced?Typical use
with sharingYes — running user’s record visibility appliesControllers, services touching user-owned data, anything user-facing
without sharingNo — class sees every recordSystem utilities, scheduled jobs, integrations, batch operations needing org-wide access
inherited sharingInherits from caller; defaults to with sharing when entered directly (e.g., from a Visualforce/Lightning context, REST endpoint, anonymous Apex)Reusable libraries that should adopt the caller’s intent
(no keyword)Behaves like without sharing by default — but the actual mode depends on where the code enters fromAvoid: ambiguous and a security review red flag

What it does and does not control

with sharing enforces record-level sharing. It does not enforce:

  • Object-level CRUD (Create/Read/Update/Delete on the object)
  • Field-level security (FLS)
  • Validation rules (those always run)

For CRUD and FLS, you need separate enforcement: WITH SECURITY_ENFORCED in SOQL, Schema.sObjectField.isAccessible() / isUpdateable() checks, or the User Mode SOQL/DML introduced in newer releases (USER_MODE / SYSTEM_MODE in SOQL and DML).

This is the most common interview gotcha: candidates think with sharing “makes Apex secure.” It only makes record sharing enforced — full security requires layering record sharing plus object/field enforcement.

Code example

public with sharing class CustomerLookupController {
    @AuraEnabled(cacheable=true)
    public static List<Account> getMyCustomers() {
        // Returns only accounts the running user can see per OWD + sharing rules.
        return [SELECT Id, Name FROM Account WHERE Industry = 'Healthcare'];
    }
}

public without sharing class LeadScoringBatch implements Database.Batchable<sObject> {
    public Database.QueryLocator start(Database.BatchableContext bc) {
        // Returns every Lead in the org regardless of who's running the batch.
        return Database.getQueryLocator('SELECT Id, Score__c FROM Lead');
    }
    public void execute(Database.BatchableContext bc, List<Lead> scope) { /* ... */ }
    public void finish(Database.BatchableContext bc) {}
}

public inherited sharing class LeadFormulaHelper {
    // Adopts the calling class's sharing mode.
    public static Decimal computeScore(Lead l) { /* ... */ }
}

When to pick which

Choose with sharing when:

  • The class is invoked by a user (controller, LWC @AuraEnabled method, REST endpoint authenticated as a user).
  • The class returns records the running user is supposed to be allowed to see.
  • The class performs DML the running user should be allowed to perform.

Choose without sharing when:

  • The class is a scheduled job, batch, or queueable performing system-level processing.
  • The class is an integration user’s entry point and must access every record by design.
  • The class implements custom security logic that intentionally bypasses sharing.

Choose inherited sharing for:

  • Reusable utility classes that should follow whatever the entry point requires.
  • Library code where forcing a mode would be inappropriate.

What if you omit the keyword?

A class with no keyword defaults to without sharing when entered directly. But if it’s called from a with sharing class, it inherits that mode. Salesforce considers omitting the keyword bad practice — security review will flag it on AppExchange submissions. Always declare an explicit mode.

Real interview question

“Your LWC calls an @AuraEnabled method that queries Accounts. The sales user complains they’re seeing Accounts owned by other reps even though OWD is Private. What’s wrong?”

Almost certainly the controlling Apex class is declared without sharing (or no keyword at all, behaving as without sharing). Change the class to with sharing so the SOQL query honors the running user’s record visibility.

Verified against: Apex Developer Guide — Using the with sharing, without sharing, and inherited sharing Keywords. Last reviewed 2026-05-17.