Short answer: a guest user is an unauthenticated visitor holding a profile and almost no ability to touch data. Since the guest user security policies became mandatory, guest users cannot own records, the org-wide default for guest access is forced to Private on every object, and the only sharing you can grant them is read-only through a guest user sharing rule. Any write path has to go through Apex declared without sharing, scoped as narrowly as you can stand.
What the platform took away
These changes arrived across the 2020 and 2021 releases and they are not optional any more. They are worth listing because most guest-access designs written before then no longer work.
- Guest users cannot own records. Records a guest creates are reassigned to a default owner configured on the site.
- Org-wide defaults for external access are Private for guest users, on every standard and custom object, and the setting is not editable.
- Guest users cannot hold View All Data or Modify All Data. The permissions are unavailable on the guest profile.
- Delete is off. Guest profiles cannot be granted delete on standard or custom objects.
- Guest users have no role, so the role hierarchy grants them nothing and owner-based sharing rules cannot reach them.
Reading data as a guest
You have two routes and they are not equally good.
The declarative route is a guest user sharing rule: a criteria-based rule on the object, targeting the site’s guest user, granting Read Only. Read Only is the ceiling. You cannot grant Read/Write through a sharing rule to a guest, and the rule has to be criteria-based, since there is no owner-based path to a user with no role.
The route I would pick is to grant the guest profile nothing at all and serve every piece of data through an Apex controller that knows exactly which records and fields are public. It costs a class. In exchange, the public surface of your org is a list of methods you can read in one sitting, rather than an object permission matrix crossed with a set of sharing rules that somebody will widen next quarter.
Writing as a guest
Creating a record is the one thing that works reasonably: Create on the object plus a layout is enough, because inserting does not require reading anything. Web-to-Case and Web-to-Lead exist precisely to avoid this problem.
Anything else needs Apex. Updating an existing record means the guest must first reach it, and the guest cannot reach anything. The pattern that holds up is a small without sharing class doing one operation, with the record identified by something unguessable and validated inside the method:
public without sharing class GuestBookingService {
public static void confirm(String bookingToken) {
List<Booking__c> found = [
SELECT Id, Status__c FROM Booking__c
WHERE Confirmation_Token__c = :bookingToken
AND Status__c = 'Pending' LIMIT 1
];
if (found.isEmpty()) { throw new AuraHandledException('Not found'); }
found[0].Status__c = 'Confirmed';
update found;
}
}
Note what is not in that method: no record Id from the client, no field the caller chooses, no object other than the one it names. A guest-facing method that accepts an Id and a field map is a data exfiltration endpoint with extra steps.
Audit your own guest users
Every Experience Cloud site and every Salesforce Site has one, and old ones tend to be generous. Find them:
SELECT Id, Name, Username, Profile.Name, IsActive
FROM User WHERE UserType = 'Guest'
Then pull ObjectPermissions for each of those profiles and read every row. Look for Read on objects the public has no business seeing, Modify All on anything, and Apex class access granted “temporarily” during a launch. Check sharing rules that name a guest user group as the target, and check whether any without sharing class is exposed to those sites.
Frequently asked
Can a guest user see other users? No. Guest users cannot see the User object’s records in the way an authenticated community user can, and designs that relied on showing an owner’s name need a formula field or a separate public record instead.
Do sharing sets work for guests? No. Sharing sets depend on a contact or account associated with the user, and a guest has neither.
What about files and images on a public page? Assets published through an asset file or a public content delivery link are the supported route. Sharing a ContentDocument to the guest user through record sharing is not.
Is a guest user licensed? Guest access is included with the site rather than consuming a named user licence, but page view and bandwidth limits apply per site, so a public page with a heavy Apex controller is a cost as well as a risk.
