1. I understand with sharing classes run in User Mode, meaning they respect permissions, field-level security and sharing rules of the current user.

  2. I understand without sharing classes run in System Mode, and they ignore permissions, field-level security and sharing rules of the current user.

But I've noted that the relevant Salesforce docs say nothing about Triggers or the classes called inside them (which I understand to be in the same execution context as the record operations that fired them)

There's a post here that suggests "the trigger still runs in system context" https://developer.salesforce.com/forums/ForumsMain?id=906F0000000904ZIAQ

What if I have a controller class without sharing doing DML causing a Trigger to be fired?

What if I have a controller class without sharing containing logic that starts a Batch job?

What I'm asking is, if (for example) the Site Guest User (a relatively unpowerful user in terms of sharing) causes a Trigger or Batch job to be fired, does that execution context have just as much clout as me causing it as a System Administrator from a Visualforce Page?

  • 2
    Field level security is not enforced in apex - it's enforced by the vf apex:input/outputField components. In apex you're expected to check it yourself. CRUD behaves similarly, but with more special cases. Commented Jan 8, 2014 at 22:50
  • I'm having REAL problems with this right now. Even in the body of a trigger, if the running user doesn't have a permission set for an object/field, then running the isAccessible() method returns false. So field level security IS VERY MUCH enforced in triggers. @ca_peterson Commented Jul 2, 2021 at 23:51

2 Answers 2


The system context is not just about sharing. From the docs:

In system context, Apex code has access to all objects and fields— object permissions, field-level security, sharing rules aren’t applied for the current user.

setting a class to run "with sharing" tells Apex to apply the current sharing rules for the current user, but field level security, object permissions etc still don't get applied. The class doesn't run in user mode though - only standard controllers or code run via execute anonymous run in user mode.

If you have a controller class without sharing that causes a trigger to be fired, the trigger will still run in the system context (i.e. no sharing, FLS, object security). If you need to respect sharing your trigger will need to delegate to a class declared as 'with sharing'.

There's a blog post from Abhinav Gupta that covers some of this, although its coming from the other side and explaining how delegating to a 'with sharing' class takes a trigger out of full system context:


Guest site user is a slightly different situation, in that some of its ability to access objects is constrained by the user license. I've hit the issue where I was trying to update something that the guest user profile should only have read/create permission on, so I thought I'd get around it using a custom controller (running in the system context). This had worked for me for contacts, but for another standard object I received an error that the license didn't support the operation. The license issue persisted even if I executed the update from an @future method. So no, I wouldn't expect it to have as much clout as the system administrator, although actions that should be prohibited by the license may sometimes work.


Triggers always run "without sharing." You could visualize a trigger as a static method in a class using the "without sharing" keyword; they are identical in behavior. Even when called from a normal "with sharing" context, such as a Visualforce page, a controller class, or another class explicitly marked as "with sharing", the trigger will always behave as if it were "without sharing." Batch jobs also honor their sharing keyword, but triggers called from batches are also run "without sharing."

What makes Guest User and System Administrator different has nothing to do with sharing at all, but is instead a different concept known as a license type. A license type is a meta-group that encompasses all profiles that contain the same license type. It defines rules of what features a particular profile could potentially access. License types are restrictive compared to profiles, because they dictate what features are available to a user, and cannot be violated under any circumstance, unlike sharing.

So, from a trigger's perspective, Read Only and System Administrator are equally powerful profiles, because they both carry the same license type, while a Chatter User or a Guest Site User license type will suffer additional restrictions, even while inside a trigger. A Guest User license can't access some objects that a System Administrator could, because the license itself prohibits access, not the sharing model.

As a common example in the Salesforce world, if an organization does not have Campaigns enabled (campaigns are a type of license), then no user in that organization can access campaigns. Even a System Administrator has no right to campaigns unless the organization has the Campaigns license. Similarly, if a Guest Site User license dictates that a certain type of object is unavailable because of a licensing restriction, then any code that attempts to violate that restriction will fail.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .