Newer Version Available
Use the with sharing, without sharing, and inherited sharing Keywords
With Sharing
Use the with sharing keyword when declaring a class to enforce sharing rules of the current user. Explicitly setting this keyword ensures that Apex code runs in the current user context. Apex code that is executed with the executeAnonymous call and Connect in Apex always execute using the sharing rules of the current user. For more information on executeAnonymous, see Anonymous Blocks.
Use the with sharing keywords when declaring a class to enforce the sharing rules that apply to the current user. For example:
1public with sharing class sharingClass {
2
3 // Code here
4
5}Without Sharing
Use the without sharing keyword when declaring a class to ensure that the sharing rules for the current user aren’t enforced. For example, to turn off sharing rule enforcement for a class that’s called by a class that has sharing rules enforced, use the without sharing keyword on the called class.
1public without sharing class noSharing {
2
3 // Code here
4
5}Inherited Sharing
Use the inherited sharing keyword when declaring a class to enforce the sharing rules of the class that calls it. Using inherited sharing is an advanced technique to determine the sharing mode at runtime and design Apex classes that can run in either with sharing or without sharing mode.
Using inherited sharing, along with other appropriate security checks, facilitates in passing AppExchange security review and ensures that your privileged Apex code isn’t used in unexpected or insecure ways. An Apex class with inherited sharing runs as with sharing if used as:
- An Aura component controller
- An @AuraEnabled method called from a Lightning web component
- A Visualforce controller
- An Apex REST service
- An asynchronous Apex class
- Any other entry point to an Apex transaction
Using the inherited sharing keyword ensures that the default is to run as with sharing. A class declared as inherited sharing runs as without sharing only if explicitly called from an already established without sharing context.
Example
1public inherited sharing class InheritedSharingClass {
2 public List<Contact> getAllTheSecrets() {
3 return [SELECT Name FROM Contact];
4 }
5}1<apex:page controller="InheritedSharingClass">
2 <apex:repeat value="{!allTheSecrets}" var="record">
3 {!record.Name}
4 </apex:repeat>
5</apex:page>Omitted Sharing Declarations
If a class isn’t explicitly declared as either with sharing or without sharing, the current sharing rules remain in effect. Therefore, the class doesn’t enforce sharing rules except if it acquires sharing rules from another class. For example, if the class is called by another class that has sharing enforced, then sharing is enforced for the called class.
There’s a distinct difference between an Apex class that’s explicitly marked with inherited sharing and one with an omitted sharing declaration. For these entry points to an Apex transaction, an omitted sharing declaration defaults to these sharing modes:
- An Aura component controller: with sharing
- An @AuraEnabled method called from a Lightning web component: with sharing
- A Visualforce controller: without sharing
- An Apex REST service: without sharing
- An asynchronous Apex class: without sharing
- Any other entry point to an Apex transaction: without sharing
Implementation in Apex Triggers
Apex triggers can’t have an explicit sharing declaration. Triggers typically run as without sharing, meaning that sharing rules for the current user aren’t enforced. However, a nested trigger that fires due to the execution of another trigger runs as with sharing in the following circumstances:
- A DML operation that runs in user mode invokes the nested trigger. For example,
given this sample code, if an account is inserted into the database, then ContactTrigger1 runs as with
sharing.
1// Trigger fires in without sharing mode 2trigger AccountTrigger1 on Account (before insert) { 3 // DML operation runs in user mode (sharing rules are applied) 4 insert as user new Contact(FirstName='Test', LastName='Test2'); 5} 6 7trigger ContactTrigger1 on Contact (before insert) { 8 // Statements in this nested trigger run in with sharing mode 9 // Calls to other classes use the declared sharing mode of each class 10} - A DML operation in a method of a class that enforces sharing rules invokes the nested
trigger. The class can enforce sharing rules explicitly with the with sharing declaration or inherit the sharing
declaration. For example, given this sample code, if an account is inserted into the
database, then ContactTrigger2 runs as with
sharing.
1// Trigger fires in without sharing mode 2trigger AccountTrigger2 on Account (before insert) { 3 // Call to ContactInsert uses sharing mode of that class (with sharing) 4 ContactInsert.run(); 5} 6 7public with sharing class ContactInsert { 8 public static void run() { 9 insert as user new Contact(FirstName='Test', LastName='Test2'); 10 } 11} 12 13trigger ContactTrigger2 on Contact (before insert) { 14 // Statements in this nested trigger run in with sharing mode 15 // Calls to other classes use the declared sharing mode of each class 16}
In both cases, after the nested trigger fires in with sharing mode, subsequent calls to other classes use the declared sharing mode of each class.
Other Implementation Details
- The sharing setting of the class where a method is defined is applied, not of the class where the method is called from. For example, if a method is defined in a class declared as with sharing is called by a class declared as without sharing, the method executes with sharing rules enforced.
- Both inner classes and outer classes can be declared as with sharing. Inner classes do not inherit the sharing setting from their container class. Otherwise, the sharing setting applies to all code contained in the class, including initialization code, constructors, and methods.
- Classes inherit the sharing setting from a parent class when one class extends another.
- Asynchronous Apex classes defined with inherited sharing always run in with sharing mode for asynchronous operations. Each asynchronous operation is a new entry point and the sharing mode is not serialized.
Best Practices
Apex without an explicit sharing declaration is insecure by default. We strongly recommend that you always specify a sharing declaration for a class.
Regardless of the sharing mode, object-level access and field-level security aren’t enforced by Apex. You must enforce object-level access and field-level security in your SOQL queries or code. For example, with sharing mechanism doesn’t enforce user’s access to view reports and dashboards. You must explicitly enforce the running user’s CRUD (Create, Read, Update, Delete) and field-level security in your code. See Enforcing Object and Field Permissions.
| Sharing Mode | When to Use |
|---|---|
| with sharing | Use this mode as the default unless your use case requires otherwise. |
| without sharing |
Use this mode with caution. Ensure that you don’t inadvertently expose sensitive data that’s normally hidden by the sharing mode. This sharing mechanism is best used to grant targeted elevation of sharing privileges to the current user. For example, use without sharing to allow community users to read records to which they wouldn’t otherwise have access. |
| inherited sharing | Use this mode for service classes that must be flexible and support use cases with different sharing modes. |