Salesforce permission sets are used to control which org data a Function can access. When you deploy your Function, you need make sure your Function is associated with a permission set that has the correct data permissions.
All deployed Functions invoked by an org use the "Functions" permission set in that org when making data requests. This permission set is automatically created when you connect your Dev Hub org with Salesforce Functions, and should be updated whenever you need to set data permissions for your Function.
To modify the data permissions for your Function, update the "Functions" permission set in the org that will be invoking the Function. You can update the permission set using the Salesforce UI, or add a
Functions.permissionset-meta.xml to your DX project’s
force-app/main/default/permissionsets folder, with the desired data permissions. For example, if you wanted to give your Function read and create access to the Account object in your org, your Functions.permissionset-meta.xml might look something like:
If you're updating your permission set in your DX project, you'll need to push your changes to your org. When using scratch orgs, you can use the
force:source:push command to push permission set changes (and other org-side changes) to your org. If you're collaborating with other developers and sharing an org and compute environment, make sure to merge your permissions changes with any changes your team has already pushed to the shared org, pulling changes to your project with
force:source:pull first if necessary. For details on synching project and scratch org changes, see Pull Source from the Scratch Org to Your Project
If you're deploying your Functions to a sandbox org, you'll also need to merge and push your permission changes, but you'll use different commands:
force:source:deploy. For more information on synching project and sandbox org changes, see Develop Against Any Org.
For more information on Salesforce permission sets, see Permission Sets Overview
Permission Sets and Local Invocation
When invoking a local running Function against a scratch org using
run:function, the Function will use the permissions of the current user, rather than the "Functions" permission set. The default scratch org user has System Admin priviledges, which means your locally running Function might have access to objects that it wouldn't normally have if running as a deployed Function.
To more accurately test how a Function will run once deployed, create a scratch org user using the "Minimum Access - Salesforce" profile. Create a permission set that provides the same object access permissions that your "Functions" permission set has, and apply this permission set to the new user. For more information on creating scratch org users, see Scratch Org Users.
Apex Invocation and Permissions
Apex code that invokes Functions is no different than other Apex code from a permissions perspective. The code runs in system mode, as described in Understanding Describe Information Permissions. Similarly, for Functions invoked via asynchronous Apex, the Apex callback run after the Function executes will run as the user that invoked the Function and will run in system mode.
Apex invocation can only invoke Functions that have been deployed to a compute environment that is associated with the org the Apex code is running in. Apex code that invokes Functions, like any Apex code, is considered "trusted code" in a given org, deployed to that org by someone that understands the security and permission requirements of that org.
Salesforce provides additional layers of permissions and security around who can execute Apex code, such as Author Apex permissions and Apex Class security. Apex code that invokes Functions may need to have class security applied so that only certain users can execute those classes. For more information on Apex Class security, see Salesforce Help: How Does Apex Class Security Work?.
Deployed Functions and Permissions
When a deployed Function is invoked, the Function runs as the "Platform Integration User" when making requests back to the org, not as the org user that invoked the Function. This means that any data access permissions that you've set on the user need to be work for the Platform Integration User as well.
Data requests are checked against the "Functions" permission set. Set the object access permissions in the "Functions" permission set to match the object access permissions for the users that will invoke the Function. For example, you may need to add your object and set ViewAllRecords or ModifyAllRecords to true in the Functions permission set. Your "Functions" permission set might end up including object permissions that you originally applied to multiple users and roles in your org.
If you encounter an error trying to access certain objects, check the license for the Platform Integration User to verify that the user who runs functions can access the objects needed. Even when you define the access in the Functions Permissions metadata file (Functions.permissionset-meta.xml), the license must also allow access to the objects.
To insert, update, or delete records of the object from a Function, return record data in the Function response and perform the DML operation in the Functions Apex callback. This approach runs Apex as the invoking user in system mode, including all its permissions.
See Give Users Access to Data for more details on setting data access permissions in your org.