[SalesForce] For the Platform Event “Automated Process” user, why do both Visualforce controller access and email sending fail

We are executing some asynchronous code that uses getContentAsPdf on a Visualforce page as the result of handling custom platform event and we get this error in the Apex Jobs listing:

First error: [UNKNOWN_EXCEPTION] You do not have sufficient privileges
to access the controller: LetterController

The "Automated Process" user (and its profile) that the events are handled under is pre-defined and not editable. And profiles would normally enforce access on the Visualforce page not the Apex controller so this error is inconsistent with that.

This looks like the same problem as this unanswered question from 6 months ago Automated Process User Permissions. (And perhaps this is related too: Salesforce doesn't merge fields on email sent in platform event context.)

Another piece of code that uses Messaging.sendEmail fails silently i.e. the message is not sent but the isSuccess() method of the result is true.

We will create a case with Salesforce about these, but has anyone done so and got these accepted as a defects? Or found a way to avoid the problems?

(The problem we are trying to solve using Platform Events is Running a Batchable under a different User than the User that called Database.executeBatch.)

Best Answer

What helped in our project regarding the class access, for example when process builder is calling InvocableMethod annotated apex method and requires access to the class, was to assign the Automated Process user a permission set. The permission set cannot be assigned in the permission set assignment page in Salesforce UI and the assignments are not visible there.

It is possible to assign it through anonymous apex though, please see the example code below:

PermissionSet permissionSet = [
    SELECT Id, Name
    FROM PermissionSet
    WHERE Name = 'Automated_Process'
];

User automatedUser = [
    SELECT Id, Name
    FROM User
    WHERE Name = 'Automated Process'
];

PermissionSetAssignment pemissionAssignment = new PermissionSetAssignment(
    PermissionSetId = permissionSet.Id, 
    AssigneeId = automatedUser.Id
);

insert pemissionAssignment;

The code above assumes that Automated_Process permission set exists in the org. This can be used also for any CI automation when creating a scratch org where the class access or some other permission is needed for the Automated Process user.

Hope this helps little bit and would be interesting to see if it might solve the VF email templates access permissions, please let me know if you have a chance to try it.

Edit Spring 21 release

As of Spring 21 the running user can be set for apex subscribers: https://help.salesforce.com/s/articleView?id=release-notes.rn_messaging_trigger_config.htm&type=5&release=230

Link to apex docs how to configure this in detail: https://developer.salesforce.com/docs/atlas.en-us.230.0.platform_events.meta/platform_events/platform_events_trigger_config.htm

So the approach described above in my original answer might not be needed anymore as the running user can be set to the different user than the Automated Process. Then access permissions can be applied to that user through permission set or profile.