Jennifer Lee in her first episode of our new "Automate This!" series.

Automate This! — Automatically Assign and Remove a Permission Set

By

Welcome to “Automate This!” In this new, live-streamed video series, we cover all things automation, from use cases and best practices to showcasing solutions built by #AwesomeAdmin Trailblazers like you. Automation allows you to remove manual tasks, drive efficiency, and eliminate friction and redundancy. With the recent announcement of the future retirement of Workflow Rules and Process Builder, we’ll focus heavily on record-triggered flow solutions this year. Watch how I use the power of Flow to assign and remove a permission set from a user, and then read all the details in the post below.

Stay tuned for next month’s Automate This! Live.


When you think about automation, the use cases that come to mind are most likely automation that your customers or users can benefit from. But did you know that you can automate user management tasks to make your life as an admin easier? Let’s #WorkSmartNotHard by automating routine, repetitive tasks for ourselves so we have more time to focus on value-added tasks, like delivering new enhancements to our users!

As an admin, it’s important to be security-minded, ensuring your org is secure and your users have least privilege access. Use our Security & Visibility Admin Configuration Kit to guide you toward a recommended solution for object-level security, field-level security, and record access.

Gone are the days you need Post-It notes to remind you to manually add and remove users from permission sets. Now, you can configure Salesforce to remember for you. With Flow, you can automatically assign and remove permission sets to/from a user as long as certain conditions are met.

Understand the object relationship

First things first. Let’s understand the relationship between user and permission sets.

User and Permission Sets are objects. The User object holds all the records of your users. The Permission Set object holds all the permission sets in your org. Then, you have the Permission Set Assignment object, which is the junction object that holds the record that ties the user to a specific permission set. A permission set assignment record has two important attributes:

  • AssignedId: This is the user ID.
  • PermissionSetId: This is the permission set ID.

User, Permission Set, and Permission Set Assignment objects, where the Permission Set Assignment object is a junction object of User and Permission Set objects

A user can have none or many permission sets, which would be reflected in the Permission Set Assignment object.

Let’s review the overall process in Salesforce

Before we log in to Salesforce and create a new flow, the first step in creating automation is to understand the overall process. There are two parts to this process: adding a user to a permission set and removing a user from a permission set.

First, let’s review the steps to manually assign a permission set to a user.

  1. Search for the user.
  2. View the user’s record.
  3. Navigate to the user’s Permission Set Assignments list.
  4. Click Edit Assignments.
  5. Select the permission set from the Available Permission Sets list to add to the Enabled Permission Sets list.
  6. Click Save.

Adding and removing permission sets to/from a user]

Note: You can assign a permission set in the user interface (UI) only if it’s listed in the Available Permission Sets list.

Let’s now review the steps to manually remove a permission set from a user.

  1. Search for the user.
  2. View the user’s record.
  3. Navigate (hover over) to the user’s Permission Set Assignments list.
  4. Locate the permission set you want to remove and click the Del link.

Removing a permission set from a user

Note: You can only delete a permission set in the UI if it’s already enabled for the user.

Your automation (aka flow) needs to accommodate for these UI restrictions or else your flow will fail.

  • Before you assign a permission set, you need to ensure the user isn’t already assigned to the permission set.
  • Before you remove a permission set, you need to ensure the user is already assigned to the permission set.

Cloudy holds a NO sign, showing you can’t assign a permission set that’s already assigned to the user. Astro holds a YES sign, showing you can remove a permission set if it’s already assigned to the user.

Let’s document the process

Before building automation in Flow Builder, I’ve found it helpful to think out the steps logically before getting my hands on the keyboard. This is especially true if you’re just learning Flow or when working on a highly complex process. It’s easier to make changes on paper than to have to refactor your configuration.

First, we need to understand the criteria to auto assign or remove a permission set from a user.

For our business requirements, when a new Finance user is added to Salesforce, the ABC permission set will be assigned. If an existing user leaves the Finance department and moves to the Sales Division, then the ABC permission set will be removed from the user.

A new person joining the Finance department is assigned the ABC permission set; a person leaving the Finance department has the ABC permission set removed.

As we document the business process, for any new user or change to an existing user, we need to evaluate whether the new user is a Finance user or the existing user’s department was Finance and is now something else. Then, if it is a new Finance user, we’ll assign a permission set. If the user was formerly part of the Finance department, we’ll remove the permission set.

The process for assigning or removing a permission set depending on whether the user is a new Finance user or was formerly part of the Finance department

Let’s take a closer look at the documented steps for assigning a new permission set.

First, we need to identify the permission set. We know it by name, but Flow needs to know the permission set ID. We get the ID by looking at the details of the permission set record. Here, we’ll follow best practice and find the permission set record by its API or developer name, as this is less likely to change than the permission set name/label.

But let’s say you can’t find the permission set by that name. Perhaps you were given the wrong name. Essentially, without that permission set record, your business process ends. You can’t do much else at that point.

When working with Flow, you need to put those safety verifications or guardrails in place to prevent your flow from failing. Visually, in Salesforce Setup, you’d be able to see in the UI whether the user is already assigned to the permission set. Essentially, behind the scenes, your flow will look to see if there’s a permission set assignment record for the user and the permission set.

If the user doesn’t have the permission set, then the next step is to assign the permission set to the user (or create the permission set assignment record). However, if the user already has the permission set, no further action is needed. Your work is done.

When we find records, we’ll use a Get Records Flow element to find information about the permission set. To determine whether the Get Records element found a permission set record, we need to make a decision. Hence, we’ll use a Decision element. Next, to see if the user is assigned to the permission set, we need to query the Permission Set Assignment object, so we’ll once again use the Get Records element. Next, we need to determine whether the Get Records element found a permission set assignment record for that user and permission set, which is done using another Decision element. Lastly, if the permission set assignment record is found, we’ll create a new permission set assignment record for the user permission set combination with a Create Records element.

The process for assigning a permission set to a user and its related Flow elements

Now, let’s look at the scenario of removing a permission set.

Again, similar to the process of assigning a permission set, we need to identify the permission set to get the permission set ID. If we can’t find the permission set, our work is done. Again, we need to put those safety verifications in place to prevent our flow from failing. Visually, in Setup, you can see whether the user is assigned to the permission set you wish to remove. Like the first scenario, you’re looking to see if there’s a permission set assignment record for that user and permission set.

If the user has the permission set, the next step is to remove it (or delete the permission set assignment record). If the user doesn’t have the permission set, no action is needed.

When we find records, we’ll use a Get Records element to find information about the permission set. To determine whether the Get Records element found a permission set record, we need to make a decision. So, we’ll use a Decision element. Next, to see if the user is assigned to the permission set, we need to query the Permission Set Assignment object, so we’ll once again use the Get Records element. Next, we need to determine whether the Get Records element found a permission set assignment record for that user and permission set, which is done using another Decision element. Lastly, if the permission set assignment record is found, we’ll remove the permission set assignment record for the user permission set combination with a Delete Records element.

The process for removing a permission set from a user and its related Flow elements

While we can design each process as its own process and its own flow, did you notice what both processes have in common? Yes, there are four common steps between the two processes. So, an even better design would be to consolidate the steps so we don’t build the same steps over and over again.

Common steps between the assign and remove permission set processes, showing the consolidated end process

One more thing before we get into Flow Builder.

We need to determine information we need (or our inputs) so Salesforce can automagically assign permission sets to a user:

  • Who is the user?
  • What is the permission set?
  • What are we looking to do (in this case—assign or remove a permission set)?

Asking for information about the user, permission set, and what to do with the permission set, as inputs into the process

These three pieces of information will be stored as text values that are three separate variables.

What’s a variable, you ask? A variable is a container that holds a piece of information for use somewhere later in the flow or to be passed off outside the flow. I think of it as a Tupperware container.

A food container representing a variable that holds a value

  • The variable varUserId will hold the user ID.
  • The variable varPermissionSetName will hold the API or developer name of the permission set name.
  • The variable varPermissionSetAction will hold the value “Add” or “Remove” which reflects what we want to do with the permission set.

We’ll use the permission set developer name to find the permission set ID because #AwesomeAdmins do not hard code IDs in their automation. If we find the permission set, we’ll store the ID in a variable called varPermissionSetId. Otherwise, the variable will be empty, signifying no permission set.

Another valuable piece of information we’ll get to within the process is whether the user is already assigned to the permission set. We’ll hold this in a variable called varDoesUserHavePermissionSet. If it’s true, we’ll store the assignee ID. Otherwise, the variable will be empty, signifying the user does not have a permission set.

We have a total of five variables that will hold important information we’ll use to make informed decisions or to take action within the flow.

Five food containers and a breakdown of the five variables needed

Let’s build our automation!

Now that we have that squared away, let’s look at how to build this in Flow Builder. Did you notice how long it took before we even logged in to Salesforce to configure?! There’s a big thought process that needs to happen before we build.

Our process will be broken into two flows: a record-triggered flow and an autolaunched flow. Our process begins with something that happens to a user record—when a new user is created or an update is made to an existing user record. This translates into a record-triggered flow. Regardless of whether the user is a new Finance user or was previously a Finance user, we didn’t want to create the same process steps to handle the Add or Remove permission set action. This takes us back to the consolidated process design, remember?

The complete process for assigning or removing a permission set for a new Finance user or a user who is no longer part of Finance

We’re going to build that consolidated Assign/Remove permission set process as an autolaunched flow, which means this flow will fire when something else triggers it. In our case, this will be triggered by a record-triggered flow. We’ll re-use the same autolaunched flow twice in our process—for the permission set assignment and permission set removal—and the flow will know what to do based on three input variables our record-triggered flow will pass to the autolaunched flow. When you re-use an autolaunched flow in another flow, it’s called a subflow. We’re essentially building a componentized flow that can be reused anytime there’s a need to assign or remove a permission set from a user. #WorkSmartNotHard. Build it once, maintain it once, and reuse it over and over again.

The parts of the process that will be addressed with an autolaunched flow

In order for our record-triggered flow to call or invoke an autolaunched flow, we need to build the autolaunched flow first.

The configured autolaunched flow to assign or remove a permission set from a user

First, select to create an autolaunched flow. Now, you’ll create five text variables.

The first text variable is varUserId. This will store the user ID passed from the record-triggered flow. Make this available for input.

  • Resource: Variable
  • Name: varUserId
  • Data Type: Text
  • Available for input: Checked

The configured varUserId text variable]

The second text variable is varPermissionSetName. This will store the permission set API or developer name passed from the record-triggered flow. Make this available for input.

  • Resource: Variable
  • Name: varPermissionSetName
  • Data Type: Text
  • Available for input: Checked

The configured varPermissionSetName text variable

The third text variable is varPermissionSetAction. This will store the value of “Add” or “Remove” passed from the record-triggered flow. Make this available for input.

  • Resource: Variable
  • Name: varPermissionSetAction
  • Data Type: Text
  • Available for input: Checked

The configured varPermissionSetAction text variable

The fourth text variable is varPermissionSetId. This will store the permission set ID when we query the Permission Set object using the value in the varPermissionSetName variable.

  • Resource: Variable
  • Name: varPermissionSetId
  • Data Type: Text

[Image: image.png][Alt text: The configured varPermissionSetId text variable

The last and fifth text variable is varUserHasPermissionSet. This will store the assignee ID when we query the Permission Set Assignment object for the user and permission set and there is a value found.

  • Resource: Variable
  • Name: varUserHasPermissionSet
  • Data Type: Text

The configured varUserHasPermissionSet text variable

Our first Flow element is a Get Records. We’ll use the permission set API or developer name to get the permission set ID. If a record is found, we’ll store the permission set ID in the variable varPermissionSetId. If no record is found, we’ll set the variable to null. This is done by checking the attribute box for “When no records are returned, set specified variables to null.”

  • Name: Lookup Permission Set Id
  • Object: Permission Set
  • Filter: Name Equals varPermissionSetName
  • How to Store Record Data: Choose fields and assign variables (advanced)
  • Where to Store Field Values: In separate variables
  • Select Variables to Store Permission Set Fields: Id → varPermissionSetId
  • “When no records are returned, set specified variables to null”: Checked

The configured Get Records element
Next, we’ll use a Decision element to determine whether or not the Get Records element found a permission set record. Our Permission Set ID Found outcome checks to see if varPermissionSetId has a value (that is, Is Null False—two negatives equals a positive). The default outcome is “No Permission Set ID Found.”

  • Name: Perm Set ID Found
  • Outcome: Permission Set ID Found | varPermissionSetId Is Null False
  • Default Outcome: No Permission Set ID Found

The configured Decision element

To see if the user is assigned to the permission set, we need to query the Permission Set Assignment object with another Get Records element to find a record with the user and the permission set. If a permission set assignment record is found, then we’ll take the assignee ID and store it in the variable varUserHasPermissionSet. If no record is found, we’ll set the variable to null by enabling the attribute “When no records are returned, set specified variables to null.”

  • Name: Lookup Permission Set Assignment
  • Object: Permission Set Assignment
  • Filter Permission Set Assignment Records:
    • AssigneeId Equals varUserId
    • PermissionSetId Equals varPermissionSetId
  • How to Store Record Data: Choose fields and assign variables (advanced)
  • Where to Store Field Values: In separate variables
  • Select Variables to Store Permission Set Fields: AssigneeId → varUserHasPermissionSet
  • “When no records are returned, set specified variables to null”: Checked

The configured Get Records element

In our next step, we need to determine whether the Get Records element found a permission set assignment record for that user and permission set using another Decision element. We have two outcomes: “Add Path - No Permission Set” and “Remove Path - Has Permission Set”.

As discussed earlier, before we can add a permission set to a user, we need to ensure the user does not already have the permission set or else the flow will fail. Here, we check that the varHasPermissionSet variable has a null value (that is, Is Null True) and the varPermissionSetAction is “Add”.

And, in order for a permission set to be removed, the user must be assigned to the permission set. Here, we check that the varHasPermissionSet variable has a value (that is, Is Null False—two negatives equals a positive) and the varPermissionSetAction is “Remove”.

This decision puts the guardrails in place in Flow, where these same guardrails are already in the permission set UI.

  • Name: Check Permission Set Assignment
  • Outcome #1: Add Path - No Permission Set | varUserHasPermissionSet Is Null True AND varPermissionSetAction Equals Add
  • Outcome #2: Remove Path - Has Permission Set | varUserHasPermissionSet Is Null False AND varPermissionSetAction Equals Remove

The configured Decision element

If the permission set assignment record is found and the varPermissionSetAction is “Add”, then we’ll create a new permission set assignment record for the user permission set combination with a Create Records element, where the AssigneeId field is set to the value in the variable varUserId and the PermissionSetId field is set to the value in the variable varPermissionSetId.

  • Name: Add User to the Permission Set
  • How Many Records to Create: One
  • How to Set the Record Fields: Use separate resources, and literal values
  • Object: Permission Set Assignment
  • Set Field Values for the Permission Set Assignment:
    • AssigneeId: varUserId
    • PermissionSetId: varPermissionSetId

The configured Create Records element

Lastly, if the decision outcome is to remove a permission set for the user, then we’ll delete the permission set assignment record for the user permission set ID combination using a Delete Records element. We’ll delete the permission set assignment record where the assigneeId equals the variable varUserId and permission set ID equals the variable varPermissionSetId combo matched.

  • Name: Remove Permission Set
  • How to Find Records to Delete: Specify Conditions
  • Object: Permission Set Assignment
  • Filter Permission Set Assignment Records: AssigneeId Equals varUserId AND PermissionSetId Equals varPermissionSetId

The configured Delete Records element

Don’t forget to test it using the Flow debugger, and activate the autolaunched flow.

With the modularized flow created, we now need to create our trigger to fire the process of assigning or removing permission sets to/from a user. As mentioned earlier, we’ll use a record-triggered flow to trigger the autolaunched flow.

For our use case, when there’s a new Finance user or a user has left Finance, we want the permission set to either be assigned or removed. The action to be taken with the permission set is done by invoking the autolaunched flow we just created. In the case of the new Finance user, a permission set will be assigned. For the user who is no longer a Finance user, a permission set will be removed.

Overall process diagram for assigning or removing a permission set for a new Finance user or a user no longer part of Finance

The record-triggered flow we build will look like this.

The configured record-triggered flow for assigning or removing a permission set for a new Finance user or a user no longer part of Finance]

The record-triggered flow starts when a user record is created or edited. We don’t have any entry conditions specified, as we want to check for new Finance users or users where the department was Finance but has changed.

  • Object: User
  • Trigger the Flow When: A record is created or updated
  • Set Entry Conditions: Custom Condition Logic is Met
    • Condition Logic: (1 AND 2) OR 3
      • Department is Changed True
      • Department Does Not Equal Finance
      • Department Equals Finance
  • Optimize the Flow for: Actions and Related Records

The configured Start element in Flow

Once a user record passes the entry criteria, we have a decision to determine what type of user this is—a new user or an existing user who is no longer part of Finance, and these are reflected in the two outcomes.

To define the new user outcome, we need the record to be new and the department to equal “Finance.”

For the Existing User Previously Finance Department outcome, we need the user ($Record.Id) to be active, the user’s previous department ($Record_Prior> Department) was “Finance,” and the user’s current department ($Record>Department) is changed.

Since this is an after save flow (that is, a record-triggered flow that fires after a record is saved in Salesforce), we need a mechanism to indicate whether a record is new, as we can’t go by the record ID is blank (which is a filter we can use in a before save flow, which fires before the record is saved in Salesforce).

We’ll introduce a new formula resource that will look at whether the record is new and the department is Finance.

  • Resource Name: NewFinanceUserFormula
  • Resource Type: Formula
  • Data Type: Boolean
  • Formula: ISNEW() && {!$Record.Department}= "Finance"

Once a user record passes the entry criteria, we have a decision to determine what type of user this is—a new user or an existing user who is no longer part of Finance, and these are reflected in the two outcomes. To define the new user outcome, we need the record to be new and the department to equal “Finance”. For the Existing User Previously Finance Department outcome, we need the user ($Record.Id) to be active, the user’s previous department ($Record_Prior> Department) was “Finance”, and the user’s current department ($Record>Department) is changed. Since this is an after save flow (that is, a record-triggered flow that fires after a record is saved in Salesforce), we need a mechanism to indicate whether a record is new, as we can’t go by the record ID is blank (which is a filter we can use in a before save flow, which fires before the record is saved in Salesforce). We’ll introduce a new formula resource that will look at whether the record is new and the department is Finance. * Resource Name: NewFinanceUserFormula * Resource Type: Formula * Data Type: Boolean * Formula: ISNEW() && {!$Record.Department}= "Finance"

Here’s how you configure the Decision element:

  • Name: New or Previously a Finance User
  • Outcome #1: New Finance User | NewFinanceUserFormula Equals True
  • Outcome #2: Existing User Previously Finance Department | All Conditions Are Met
    • $Record.IsActive Equals True
    • $Record_Prior> Department Equals Finance
    • $Record>Department is Changed True

The configured Decision element

For the New Finance User outcome, we’ll add a subflow interaction, which will allow this record-triggered flow to invoke the autolaunched flow. Locate and select the autolaunched flow we created.

Here, we’ll include the three input variables and pass the following information to our subflow:

  • varPermissionSetAction: Add (This specifies we want to add a permission set.)
  • varPermissionSetName: ABC_Permission_Set (This is the permission set’s API name.)
  • varUserid: {!$Record.Id} (We’re using the ID of the user record that triggered the record-triggered flow.)

This will tell the subflow that I want to add the ABC permission set to the user record that triggered the process.

For the New Finance User outcome, we’ll add a subflow interaction, which will allow this record-triggered flow to invoke the autolaunched flow. Locate and select the autolaunched flow we created. Here, we’ll include the three input variables and pass the following information to our subflow: * varPermissionSetAction: Add (This specifies we want to add a permission set.) * varPermissionSetName: ABC_Permission_Set (This is the permission set’s API name.) * varUserid: {!$Record.Id} (We’re using the ID of the user record that triggered the record-triggered flow.) This will tell the subflow that I want to add the ABC permission set to the user record that triggered the process.

For the Existing User Previously Finance Department outcome, we’ll add another subflow interaction. Locate and select the autolaunched flow we created.

We’ll include the three input variables and pass the following information to our subflow:

  • varPermissionSetAction: Remove (This specifies we want to remove a permission set.)
  • varPermissionSetName: ABC_Permission_Set (This is the permission set’s API name.)
  • varUserid: {!$Record.Id} (We’re using the ID of the user record that triggered the record-triggered flow.)

This will tell the subflow that I want to remove the ABC permission set from the user record that triggered the process.

Configured subflow to remove the permission set

Test both expected outcomes (new Finance user and an existing user who used to belong to Finance) and one where the user does not meet the entry criteria (that is, new user with a department that’s not Finance) using Flow debugger. Lastly, activate the flow.

As additional scenarios come up for automatically assigning or removing a permission set, you can create a new record-triggered flow that invokes the autolaunched flow as subflows.

Resources

Want to see more good stuff? Subscribe to our channel!

SUBSCRIBE TODAY
Jennifer Lee and Sunil Matthew in a new episode of "Automate This!"

Automate This! — Migrate Processes to Flow and Use Custom Notifications

Welcome to another “Automate This!” In this live-streamed video series, we cover all things automation, from use cases and best practices to showcasing solutions built by #AwesomeAdmin Trailblazers like you. With automation, you can remove manual tasks, drive efficiency, and eliminate friction and redundancy. In this episode, let’s see how Sunil Mathew used Flow and […]

READ MORE
Jennifer Lee and Michelle Hansen in a new, live episode of "Automate This!"

Automate This! — Resolve Mixed DML Errors with Platform Events

Welcome to another “Automate This!” In this live-streamed video series, we cover all things automation, from use cases and best practices to showcasing solutions built by #AwesomeAdmin Trailblazers like you. With automation, you can remove manual tasks, drive efficiency, and eliminate friction and redundancy. In this episode, let’s see how Michelle Hansen eliminates those pesky […]

READ MORE
Jennifer Lee and Jessie Rymph in a new "Automate This!" yesterday.

Automate This! — How to Use Loops in Flow

Welcome to another “Automate This!” In this live-streamed video series, we cover all things automation, from use cases and best practices to showcasing solutions built by #AwesomeAdmin Trailblazers like you. With automation, you can remove manual tasks, drive efficiency, and eliminate friction and redundancy. In this episode, let’s see how Salesforce.org Senior Solution Developer Jessie […]

READ MORE

Have an Idea for a Story?

We are all about the community and sharing ideas.
Do you have an interesting idea or useful tip that you want to share?

SHARE YOUR IDEA