Protect Your Application from Sharing Violations
When using Apex, ensure that you don’t inadvertently expose sensitive data. Apex generally runs in system context, which grants it access to all objects and fields without applying object permissions, field-level security, or sharing rules for the current user. Usually, system context provides the correct behavior for operations, such as triggers, that need access to all data in a Salesforce org. However, you can also specify that certain Apex classes must enforce the sharing rules that apply to the current user.
There are three keywords to remember for sharing rules.
- With sharing: Use this to enforce the current user's sharing rules for a class. Here's sample
code.
1public with sharing class ProjectService { 2 public static List<Project__c> getProjects() { 3 // This query respects sharing rules for Project__c 4 return [SELECT Id, Name, Status__c FROM Project__c]; 5 } 6} 7 - Without sharing: Use this to ensure the current user's sharing rules are not enforced for a
class. Here's sample
code.
1public without sharing class ProjectServiceWithoutSharing { 2 public static List<Project__c> getProjects() { 3 // This query ignores sharing rules for Project__c 4 return [SELECT Id, Name, Status__c FROM Project__c]; 5 } 6} 7 - Inherited sharing: Use this to run an Apex class in the same sharing mode as the class that
called it. Inherited sharing clarifies intent and avoids ambiguity that can arise from an
omitted sharing declaration, helping ensure privileged Apex code isn't used
insecurely.
1public inherited sharing class ProjectServiceInheritedSharing { 2 public static List<Project__c> getProjects() { 3 // Sharing mode depends on caller context 4 return [SELECT Id, Name, Status__c FROM Project__c]; 5 } 6} 7
Enforcing the current user's sharing rules can impact the following.
- SOQL and SOSL queries: Queries can sometimes return fewer rows than they would in system context.
- Data Manipulation Language (DML) operations: Operations might fail if the current user lacks the necessary permissions. For example, if a user specifies a foreign key value that they don’t have access to.
General Considerations for Enforcing Sharing Rules
- Always include a sharing declaration on classes that have database operations.
- Generally, declare classes as “with sharing” to ensure principle of least privilege.
- Some use cases, such as controller classes, that are accessible to a guest user may be exempted.
- Always make a conscious decision when declaring a class as “inherited sharing” or “without
sharing”.
- Don’t grant unauthorized access to users in every possible execution flow.
- Apex triggers can’t have an explicit sharing declaration and run as without sharing. Therefore, hand code over to Handler classes instead of writing code in triggers.
To learn more about sharing rules enforcement, check out the Secure Server-Side Development module on Trailhead. You can also look at Use the with sharing, without sharing, and inherited sharing Keywords for more information on sharing rules.