are Triggers (and their delegated classes) or Batch affected by sharing?

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:

http://www.tgerm.com/2011/03/trigger-insufficient-access-cross.html

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.