
Managing user access is one of the most important aspects of a Salesforce implementation. From assigning permission sets and permission set licenses to adding users into queues or public groups, automation ensures these processes remain consistent, efficient, and secure. Although in most cases, we immediately turn to record-triggered flows to handle these tasks, Salesforce offers a dedicated automation tool specifically designed for managing user access. In many situations, this tool can simplify and streamline access management. That said, flows still play a crucial role when you need more flexibility. Here is a comparison of flow and user access policies, with guidance on when to use each and how to choose the best approach for your use case.
User Access Policies
User Access Policies are a standard Salesforce feature that make it easier for admins to manage user access without heavy automation setup. They let you automatically assign permission sets, grant permission set licenses, or remove access based on simple rules you define. You can set a policy to run whenever a user is created or updated, much like a record-triggered flow. The big difference is that user access policies are purpose-built for access management, so they’re quicker to configure and easier to maintain for these types of tasks.
At first glance, User Access Policies may seem like the perfect tool for all access-related automations. However, they come with several limitations that can make them unsuitable for more complex scenarios. This is where record-triggered flows step in, offering the flexibility and customization needed to handle a wider range of use cases.
Let’s take a closer look at when flows become the more suitable option.
Comparison of Flow and User Access Policies
Entry Criteria
It’s possible to set entry criteria for user access policies, but they do come with some notable limitations. First, you can’t define custom logic. The criteria are restricted to simple AND conditions, which can be a significant drawback. Second, only a limited set of User field types are supported: Text, Picklist, Number, and Checkbox. While this may cover some scenarios, many real world use cases require referencing other field types, such as formula fields or even fields from related records. For example, pulling in contact fields for Experience Cloud users.
User access policies also offer some unique advantages. For example, their entry criteria can reference Groups, Queues, Permission Sets, Permission Set Groups, and Package Licenses. This is something record-triggered flows don’t support.
Complexity
User access policies work in a simple, rule-based way. When the entry criteria match, they grant or revoke access, similar to how workflow rules operate. They don’t allow extra logic or branching. On the other hand, record-triggered flows give you endless flexibility. You can add complex conditions, reference related records, and design advanced automation paths.
Therefore, if your requirement is simple, go with user access policies. If it’s more complex, build a record-triggered flow.
No Reverse Actions
One important limitation of user access policies is that they don’t roll back actions when a user no longer meets the policy criteria. Once the policy assigns a permission set, license, or group membership, that access remains in place even if the user’s details change.
In contrast, record-triggered flows give you full control. You can check a user’s previous role, profile, or other conditions and design the flow to revoke access when those conditions no longer apply.
For example, if you assign a permission set to all users with a specific role, a user access policy won’t remove it if the role changes. But with a flow, you can easily check the prior role and automatically take back the permission set when the user no longer qualifies.
Duplicate Assignments Handling
With record-triggered flows, you need to add extra checks before assigning a permission set. If the permission set is already assigned, the flow can’t assign it again, so you have to build logic to verify that first. This means adding a few more elements to your flow. On the other hand, user access policies handle this automatically. If the permission set is already in place, the policy simply skips the assignment, saving you the extra work.
Example
Let’s say you want to assign the "View Account Fields" permission set to users who meet all of the following conditions:
- The user’s Role is CEO or CFO
- The user is Active
- The user’s Department is "Management"
You can configure this directly with a User Access Policy. Simply set up entry criteria using Role, IsActive, Department and define the action to assign the "View Account Fields" permission set. Once the criteria are met, Salesforce automatically applies the permission set to the user.

If you want to use a record-triggered flow for this scenario, here’s how you can build it:
- Set the entry criteria using a formula that checks if the user’s Role is CEO or CFO, the user is Active, and the Department equals Management.
- Get the Permission Set record to retrieve its ID.
- Check for existing assignment by getting the Permission Set Assignment object.
- Add a Decision element to see if the user already has the permission set.
- Create a Permission Set Assignment record only if the user doesn’t already have it.
This approach gives you full control but requires more steps compared to user access policies, which handle duplicate assignments automatically.

Just create a profile for CEO and call it a day. Too much work to use flows or access policies. Best to wait for Salesforce to fix permission set assignments so that it scales as people move around an org. Not about to watch users keep permissions from when they were an intern years ago. Salesforce just being lazy because no money in permissions set management.
Yumi, I tried to create a Flow on GroupMember (when a user is assigned to a group), and it seems like not an option... So User Access Policies seems to be the only option for that.
What do you think?
I agree, you should use User Access Policies or Apex code for that.