In a Salesforce Apex class, we can define the sharing settings to control data access and ensure security within the Salesforce platform. To manage how Apex classes follow record-level access, we use keywords such as with sharing, without sharing, inherited sharing, and omitted sharing in Salesforce Apex.
In this blog, we’ll learn what each of these sharing keywords means, when to use them, and how they affect data visibility in the Apex code.
What is the Use of Sharing Keywords in the Apex Class?
In Salesforce, the sharing model record-level security is managed through Profiles, Sharing settings, Ownership, Role Hierarchy, and Sharing rules. By using the “Sharing keyword“, we can ensure that the apex class we created follows to Salesforce’s record-level sharing rules, which are based on OWD, role hierarchies, and sharing rules.
By default, Apex code runs in system context, which can bypass these rules and expose data that the user should not usually see. To manage this, Apex provides four sharing options: with sharing, without sharing, inherited sharing, and omitting the sharing keyword.
Let’s see the implementation and use case of these four sharing keywords in Salesforce Apex.
Use case scenario:
Let’s consider a scenario where there is a custom object Project_c, and project records are shared by the CEO and the manager. In the Salesforce role hierarchy, the CEO is above the manager, so he will be able to access all project records, but the manager can only share those records owned or shared with him.
To show the output according to sharing rules, I have assigned the CEO role to my profile and the manager role to another user with a Salesforce platform license.
With Sharing Keyword in Salesforce Apex
In a Salesforce Apex class, when we use the ‘With sharing‘ keyword, the code runs in the context of the current user, which means it enforces the sharing rules for the current user. When we use the “With sharing” keyword, then records not shared with the current user are not accessed by the apex code in this context.
According to the above-mentioned scenario, we will run the apec class in the context of a user with a manager role. In this Apex class, we will use the “with sharing” so the code will follow the sharing rules in the context of the current user.
public with sharing class ApexWithSharing {
public static List<Project__c> getAllProjects() {
return [
SELECT Id, Name, Status__c, Owner.Name
FROM Project__c
ORDER BY CreatedDate DESC
];
}
}Now, enter the code below in the anonymous window to execute the apex class method.
List<Project__c> projects = ApexWithSharing.getAllProjects();
for (Project__c project : projects) {
System.debug('Project Name: ' + project.Name +
', Status: ' + project.Status__c +
', Owner Name: ' + project.Owner.Name);
}In the Execution log window, select the ‘Debug only‘ checkbox, and you will see the records owned by the current user.

The current user is getting the records owned by him in the manager role in the role hierarchy. On the other hand, when the CEO can see all the records because he is above in the role hierarchy.
Without Sharing Keyword in Salesforce Apex
In the Salesforce Apex class, the without sharing keyword allows the user to bypass sharing rules and view the details of the records that they do not own.
Now, there are project records, and the user with the manager role wants to know how many active projects there are in the org, so basically, the count of active projects. In this, the user will view the active status of records owned by others.
For this requirement, we create the Apex Class Project Sharing with the code below.
public without sharing class ProjectSharing {
@AuraEnabled(cacheable=true)
public static Integer getTotalProjectsCount() {
return [
SELECT COUNT()
FROM Project__c
WHERE Status__c = 'Working'
];
}
}To call the apex class method, enter the code below in the anonymous window and execute it.
Integer activeProjectCount = ProjectSharing.getTotalProjectsCount();
System.debug('Total Active Projects: ' + activeProjectCount);In the Execution log window, select the checkbox, and you will see the record count of the active projects irrespective of whether those records are accessible to the current users or not.

Inherited Sharing in Salesforce Apex
This Apex sharing feature was introduced in the Winter ’19 release. In the Inherited Sharing feature, we can call the class in both “With Sharing” and “Without Sharing” sharing settings, depending on the context in which the class is called.
This keyword implements the sharing settings as the same as the class in which the current class is called. When we call the inherited sharing class from a with sharing class, it will follow the sharing rules and restrict any data from being accessed.
When the Inherited class is called from the non-sharing class, it will not follow the sharing rules and expose all the data. If we don’t define with or without sharing in the Inherited class, it runs “with sharing” by default.
For example, we have the Inherited Sharing class below, which follows the sharing rules of the class that calls it.
public inherited sharing class ApexInheritedSharing {
@AuraEnabled(cacheable=true)
public static List<Project__c> getProjects() {
return [SELECT Name, Owner.Name FROM Project__c];
}
}Calling the Inherited Sharing class from “with sharing class“:
public with sharing class ApexWithSharing {
@AuraEnabled(cacheable=true)
public static List<Project__c> getProjectsInherited() {
return ApexInheritedSharing.getProjects();
}
}The above class will return the records owned by the current user because it follows the sharing rules set to “with sharing“.
Anonymous code in the “With Sharing” class to execute it.
List<Project__c> projects = ApexWithSharing.getProjectsInherited();
for (Project__c project : projects) {
System.debug('Project Name: ' + project.Name + ', Owner Name: ' + project.Owner.Name);
}Output:

Since we use the “with sharing“, the inherited class ApexInheritedSharing will run in the context of a current user, following the sharing rules and return only records owned by the current user.
Calling the Inherited Sharing class from “without sharing class“:
public without sharing class ApexWithSharing {
@AuraEnabled(cacheable=true)
public static List<Project__c> getProjectsInherited() {
return ApexInheritedSharing.getProjects();
}
}When we call the inherited class “ApexInheritedSharing“, using the without sharing keyword, then it will display all the records in the context of the current user by overriding the permission rules.
Use the below anonymous code in the With Sharing class to execute it:
List<Project__c> projects = ApexWithSharing.getProjectsInherited();
for (Project__c project : projects) {
System.debug('Project Name: ' + project.Name + ', Owner Name: ' + project.Owner.Name);
}Output:

Since we used the “without sharing” in the calling class, the inherited class overrides the sharing rules and returns all the records irrespective of the current user context.
So, this is how the Inherited sharing works in Salesforce Apex, where it inherits the sharing setting from the calling class.
Default Sharing or Omitted Sharing in Salesforce Apex
When we don’t mention any sharing keyword in the Apex class, such as “with” or “without” sharing, then it is called Default Sharing or Omitted Sharing.
This is a very important class sharing, as this is the most complicated and unpredictable sharing setting for the apex classes. In this, we don’t want to use the keyword like “Omitted” or “Default”, it’s just that, if you don’t use any sharing keyword, it takes the default.
The code of default or omitted apex class is as below:
public class ProjectSharing {
@AuraEnabled(cacheable=true)
public static List<Project__c> getProjects(){
return return [SELECT Name, Owner.Name FROM Project__c];
}
}Since no sharing keyword is defined, it will bypass the sharing rules and return all records to the current user.
Using Omitted sharing with Inherited Class in Salesforce Apex
It is always recommended to avoid omitted sharing, as it is not good for data security. There are some considerations that you should be aware of while using the omitted sharing with the inherited class.
- If a class with “with sharing” is calling a method of a class with omitted sharing, which in turn calls a method of a class with inherited sharing, then it will run in with sharing mode, as the calling class is in with sharing mode and the omitted class is established as with sharing context.
- If a class with “without sharing” is calling a method of a class with omitted sharing, which in turn calls a method of a class with inherited sharing, then it will run in without sharing mode, as the calling class is in without sharing mode and the omitted class is established as without sharing context.
This way, we can implement the sharing rules context in the Salesforce Apex class to restrict or allow users to access the records and the data in the Salesforce org.
You may also like to read:
- Data Manipulation Language(DML) in Salesforce Apex
- Salesforce Object Search Language (SOSL) in Apex
- Batch Apex in Salesforce With Examples
I am Bijay Kumar, the founder of SalesforceFAQs.com. Having over 10 years of experience working in salesforce technologies for clients across the world (Canada, Australia, United States, United Kingdom, New Zealand, etc.). I am a certified salesforce administrator and expert with experience in developing salesforce applications and projects. My goal is to make it easy for people to learn and use salesforce technologies by providing simple and easy-to-understand solutions. Check out the complete profile on About us.