Greenery and text that says, "Automate the Assignment and Removal of Permission Set Groups." "

Automate the Assignment and Removal of Permission Set Groups

By

In the first episode of Automate This!, a new livestream content series focused on all things automation, I presented a solution for automating the assignment and removal of permission sets. This blog post will cover a related solution, the automation of the assignment and removal of permission set groups. Don’t know what permission set groups are? Check out the Introducing the Next Generation of User Management: Permission Set Groups blog post for an overview.

Automation is for everyone, not just for your customers or end users but also for you as an admin. Let’s make this the year where we #WorkSmartNotHard by automating routine, repetitive tasks for ourselves so we can focus on those more value add 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 only the access they need to get their work done. Use our Security and Visibility Admin Configuration Kit to guide you toward a recommended solution for object-level security, field-level security, and record access.

Stop sticking Post-it notes on your computer to remind you to manually add and remove users from permission set groups. Get Salesforce to do the remembering for you! Use Flow Builder to automagically assign and remove permission set groups to/from a user as long as certain conditions are met.

Let’s walk through how our #AwesomeAdmin, Addison Dogster, completes the process and configuration work needed to automate this task.

Understand the object relationship

First, Addison creates a permission set group called Cloudy’s PSG, assigns a couple of permission sets (Export Reports and Edit Accounts) to the permission set group, and assigns the permission set group to herself. Then, she exports the records from the following objects using Data Loader.

Note: You must check the box for “Show all Salesforce objects” to see these objects.

Data Loader with permission set group related objects shown

Permission Set Group (PermissionSetGroup): This is the object that holds the high-level setup of a permission set group. In this object, you can get the Permission Set Group Developer Name (DeveloperName) and Permission Set Group ID (Id).

Permission set group record with DeveloperName and ID fields highlighted

Permission Set (PermissionSet): Represents a set of permissions that’s used to grant more access to one or more users without changing their profile or reassigning profiles. PermissionSet has a read-only child relationship with PermissionSetGroup. Here, important fields are the permission set name (Label) and the permission set type (“Session” represents permission set group and “Regular” represents a permission set).

Permission set records with ID, Label, Name, PermissionSetGroupId, and Type fields highlighted

Permission Set Group Component (PermissionSetGroupComponent): This is a junction object that relates the PermissionSetGroup and PermissionSet objects via their respective IDs and enables permission set group recalculation to determine the aggregated permissions for the group. In this object, you can see the related permission set group (PermissionSetGroupId) and the permission sets associated to it (PermissionSetId).

 Permission set group component records with PermissionSetGroupId and PermissionSetId fields highlighted

Permission Set Assignment (PermissionSetAssignment): Represents the association between a User and a PermissionSet (which can be a permission set or permission set group). Here, the important fields are the assigned user (AssigneeId), the permission set the user is assigned to (PermissionSetId), and the Permission Set Group the user is assigned to (PermissionSetGroupId).

Permission set assignment records with AssigneeId, PermissionSetGroupId, and PermissionSetId fields highlighted

When Addison looks at the permission set assignment data, she sees that Jared Dunn’s user ID (005B0000007N5MQIA0) is assigned to two permission sets, one of which comprises of a permission set group. But when she looks at her user record, she only has the one permission set group and no permission sets assigned. So, what is this mystery permission set?

Addison enters the permission set ID “0PSB0000001HY2aOAG” into the URL after https://servername.salesforce.com/or https://mydomainname.my.salesforce.com/ to see what this permission set is. She gets the following error:

“Insufficient Privileges

You do not have the level of access necessary to perform the operation you requested. Please contact the owner of the record or your administrator if access is necessary. For more information, see Insufficient Privileges Errors.”

Interesting. This must be a system generated/owned permission set.

Addison noticed that when she went back to Setup Home, there are two Cloudy’s PSG items listed in her Most Recently Used list. One is a permission set group and the other is a permission set:

Two Cloudy’s PSG configuration items in Setup Home

It appears that when a new permission set group is created, there’s a system generated permission set created with the same permission set group name.

Now that Addison understands the data relationship with permission set group, permission set, and permission set assignment, she can move into automating the assignment/removal of a permission set group using a flow, which will look like this:

 Autolaunched flow to automatically assign or remove permission set groups to/from a user

Review the overall process in Salesforce

Before Addison logs in to Salesforce and creates a new flow, the first step in creating automation is to understand the overall process. There are two parts to the process: adding a user to a permission set group and removing a user from a permission set group.

First, Addison reviews the steps to manually assign a permission set group to a user:

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

User interface for adding and removing permission set groups to/from a user

Note: The user interface (UI) allows you to assign a permission set group only if it’s available in the Available Permission Set Groups list.

6. Click Save.

Addison will now review the steps to manually remove a permission set group from a user:

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

User interface for removing a permission set group from a user

Note: The UI only allows you to delete a permission set group if it’s already enabled for the user.

Addison’s automation (aka flow) needs to accommodate for these UI restrictions or else the flow will fail.

  • Before Addison assigns a permission set group, she needs to ensure the user is not already assigned to the permission set group.
  • Before Addison removes a permission set group, she needs to ensure the user is already assigned to the permission set group.

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

Document the configuration process

Before Addison logs in to Salesforce and starts building the automation in Flow, she gets out a piece of paper and a pencil. She’s found it helpful especially when she was just learning Flow, or otherwise working on a highly complex process, to think out the steps logically on paper before she gets her hands on a keyboard. It’s easier to make changes on paper than to have to refactor her configuration. No one has time for that! #WorkSmartNotHard

First, she needs to understand the criteria to auto assign or remove a permission set group from a user.

For Addison’s business requirements, as shown in the illustration below, when a new marketing user is added to Salesforce, Cloudy’s PSG permission set group will be assigned. If an existing user leaves the marketing department and moves into the operations division, Cloudy’s PSG permission set will be removed from that user.

A new person joining the marketing department is assigned Cloudy’s permission set group, and a person leaving the marketing department has Cloudy’s permission set group removed.

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

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

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

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

But let’s say you can’t find the permission set group by that name. Perhaps you were given the wrong name. Essentially, without that permission set group record, your business process ends. We can’t do much else at this 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 would be able to see in the UI whether the user is already assigned to the permission set group. Behind the scenes, your flow will look to see if there’s a permission set assignment record for the user and the permission set group the user is assigned to.

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

The animated GIF below illustrates the process for assigning a permission set group. It takes it a step further by translating the steps into related Flow elements. This will be handy when we build our flow.

When we find records, we’ll use a Get Records element to find information about the permission set group. To determine whether the Get Records element found a permission set group 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 group, 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 group, 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 group combination with a Create Records element.

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

Now, let’s take the scenario of removing a permission set group:

  • Similar to the process of assigning a permission set group, we need to identify the permission set group to get the permission set group ID.
  • Again, if we can’t find the permission set group, our work is done.
  • We also 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 group 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 group.
  • If the user has the permission set group, then the next step is to remove (or delete the permission set assignment record). If the user does not have the permission set group, no action is needed.

When we find records, we’ll use a Get Records element to find information about the permission set group. To determine whether the Get Records element found a permission set group 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 group, 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 group, 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 group combination with a Delete Records element.

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

We can design each process as its own process and its own flow, but did you notice what both processes have in common? There are four common steps between the two processes. An even better design would be to consolidate the steps so we’re not building the same steps again and again.

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

One more thing before we go into Flow Builder.

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

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

Inputs into the process include “Who is the user?”, “Who is the permission set group?", and "What are we looking to do (in this case - assign or remove a permission set group)?"

These three pieces of information will be stored as text values as 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 varPermissionSetGroupDeveloperName will hold the API or developer name of the permission set group.
  • The variable varPermSetGroupAction 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 group ID, because #AwesomeAdmins do not hard code IDs in their automation. Hard-coding is never a best practice, no matter what you’re doing in Salesforce. Hard-coded references may cause issues when new functionality is released and make it difficult to troubleshoot problems when they arise. So don’t do it!

If we find the permission set group, we’ll store the ID in a variable called varPermissionSetGroupId. Otherwise, the variable will be empty, signifying no permission set group.

Another valuable piece of information we’ll get to within the process is whether the user is already assigned to the permission set group. We’ll hold this in a variable called varDoesUserHasPSG. 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 group.

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 description of the five variables needed

Now, let’s build our automation!

With that out of the way, let’s build this in Flow. Did you notice how long it took before we even logged in to Salesforce?! There’s a substantial thought process that needs to happen before we build our configuration.

Our process will be broken down into three flows: two record-triggered flows and an autolaunched flow. It 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 two record-triggered flows. One process handles whether the user is a new marketing user. The other process focuses on whether the user was previously part of marketing. Both will use the same process steps to handle the add or remove permission set group action. Remember the consolidated process design?

The complete process for assigning or removing a permission set group for a new marketing user, an existing user joining the marketing department, or a user who is no longer part of marketing

We’re going to build that consolidated assign/remove permission set group process as an autolaunched flow, which means this is a flow that will fire when something else triggers it. In our case, this will be triggered by one of two record-triggered flows. We will reuse 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 reuse an autolaunch flow in another flow, it’s called a subflow. In this case, we’re building a componentized flow that can be reused anytime there’s a need to assign or remove a permission set group from a user. We build it once, maintain it once, and reuse it over and over again. #WorkSmartNotHard

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

In order for our record-triggered flows 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 group from a user

  1. First, select to create an autolaunched flow.
  2. Next, 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

Configured varUserId text variable

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

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

Configured varPermissionSetGroupDeveloperName text variable

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

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

Configured varPermSetGroupAction text variable

The fourth text variable is varPermissionSetGroupId. This will store the permission set group ID when we query the permission set group object using the value in the varPermissionSetGroupDeveloperName variable.

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

Configured varPermissionSetId text variable

Our last and fifth text variable is varUserHasPSG. This will store the assignee ID when we query the permission set assignment object for the user and permission set group and there is a value found.

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

Configured varUserhasPSG text variable

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

  • Name: Get PSG Id
  • Object: Permission Set Group
  • Filter: DeveloperName Equals varPermissionSetGroupDeveloperName
  • How Many Records to Store: Only the first record
  • 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 → varPermissionSetGroupId
  • When no records are returned, set specified variables to null: Checked

Configured Get Records element

Next, we’ll use a Decision element to determine whether the Get Records element found a permission set group record. Our Found outcome checks to see if varPermissionSetGroupId has a value (that is, Is Null False—two negatives equal a positive). The default outcome is “Not Found”.

  • Name: PSG Found
  • Outcome: Found | varPermissionSetGroupId Is Null False
  • Default Outcome: Not Found

Configured Decision element

To see if the user is assigned to the permission set group, 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 group. If a permission set assignment record is found, then we’ll take the assignee ID and store it in the variable varUserHasPSG. If there’s no record found, we’ll set the variable to null by checking the box for “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
    • PermissionSetGroupId Equals varPermissionSetGroupId
  • 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 → varUserHasPSG
  • When no records are returned, set specified variables to null: Checked

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 group using another Decision element. We have two outcomes: “Add to PSG – Not Assigned” and “Remove PSG – Assigned”.

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

In order for a permission set group to be removed, the user must be assigned to the permission set. Here, we check that the varHasPSG variable has a value (that is, Is Null False—two negatives equal a positive) and the varPermSetGroupAction is “Remove”.

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

  • Name: Is User Already Assigned?
  • Outcome #1: Add to PSG – Not Assigned | varUserHasPSG Is Null True AND varPermSetGroupAction Equals Add
  • Outcome #2: Remove PSG – Assigned | varUserHasPSG Is Null False AND varPermSetGroupAction Equals Remove

Configured Decision element

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

  • Name: Add User to PSG
  • 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: varPermissionSetGroupId

Configured Create Records element

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

  • Name: Remove PSG from User
  • How to Find Records to Delete: Specify Conditions
  • Object: Permission Set Assignment
  • Filter Permission Set Assignment Records: AssigneeId Equals varUserId AND PermissionSetGroupId Equals varPermissionSetGroupId

Configured Delete Records element

Let’s save the autolaunched flow and name it “Assign or Remove a user from a Permission Set Group”.

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 set groups to/from a user. As mentioned earlier, we’ll use a record-triggered flow to trigger the autolaunched flow.

The first of the two record-triggered flows Addison builds looks like this. This simple, one-step record-triggered flow fires when a new marketing user is created or an existing user’s department is now marketing.

Configured record-triggered flow for assigning or removing a permission set for a new marketing user or when an existing user’s department is now marketing

The second record-triggered flow fires when an existing user is no longer part of the marketing department.

Configured record-triggered flow to handle the process when an existing user is no longer part of the marketing department

Let’s walk through the configuration of the first record-triggered flow.

The record-triggered flow starts when a user record is created or edited and the user’s department is marketing. Since we’re calling our autolaunched flow from this flow, we’ll use the Actions element, so we select Actions and Related Records.

  • Object: User
  • Trigger the Flow When: A record is created or updated
  • Set Entry Conditions: All Conditions Are Met (AND)
    • Department Equals Marketing
  • When to Run the Flow for Updated Records: Only when a record is updated to meet the condition requirements
  • Optimize the Flow for: Actions and Related Records

Configured Start element in the flow

Next, we want to use an Action; specifically, we want to reference a subflow (the autolaunched flow) to add the permission set group to the user if they don’t already have the permission set group assigned.

  • Subflow name: Assign or Remove a user from a Permission Set Group
  • Set the variables as follows and toggle so the variable is included:
    • varPermissionSetGroupDeveloperName: Cloudy_PSG (This is the API name for the permission set group.)
    • varPermSetGroupAction: Add (We want to add a permission set group to the user.)
    • varUserId: {!$Record.Id} (This is the record ID that fired off the record-triggered flow.)

Configured subflow to add a permission set group

Let’s save this record-triggered flow as “New Marketing User or User Updated to Marketing”.

Test both expected outcomes (new marketing user and an existing user who moved to marketing) and one where the user does not meet the entry criteria (that is, new user with a department not marketing) using the Flow debugger. Then, activate the flow.

Now, let’s build the second record-triggered flow.

This record-triggered flow starts when a user record is updated and the user’s department is not marketing and the user’s department has changed. Since we’re calling our autolaunched flow from this flow, we’ll use the Actions element, so we select Actions and Related Records.

  • Object: User
  • Trigger the Flow When: A record is updated
  • Set Entry Conditions: All Conditions Are Met (AND)
    • Department Does Not Equal Marketing
    • Department Is Changed True
  • When to Run the Flow for Updated Records: Every time a record is updated and meets the condition requirements
  • Optimize the Flow for: Actions and Related Records

Configured Start element of the record-triggered flow

Next, we need a Decision element to determine whether the user was previously part of the marketing department. For our outcome “Part of Marketing”, we need to look at the user record’s department field prior value to see if it was “Marketing”. The default outcome is set to “Not Previously Part of Marketing”.

  • Name: Was the User Previously Marketing
  • Outcome #1: Part of Marketing
    • $Record__Prior>Department Equals Marketing
    • When to Execute Outcome: If the condition requirements are met
  • Default: Not Previously Part of Marketing

Configured Decision element

For the “Part of Marketing” decision outcome, we want to use an Action; specifically, we need to reference our autolaunched flow as a subflow to remove the permission set group from the user if they already have the permission set group assigned.

  • Subflow name: Assign or Remove a user from a Permission Set Group
  • Set the variables as follows and toggle so the variable is included:
    • varPermissionSetGroupDeveloperName: Cloudy_PSG (This is the API name for the permission set group.)
    • varPermSetGroupAction: Remove (We want to remove a permission set group from the user.)
    • varUserId: {!$Record.Id} (This is the record ID that fired off the record-triggered flow.)

Configured subflow to remove a permission set group

Let’s save this record-triggered flow as “User No Longer Part of Marketing”.

Test the expected outcome (an existing user who moved out of marketing) and one where the user does not meet the entry criteria (an existing user who was never part of marketing) using Flow debugger, and activate the flow.

As additional scenarios come up for automatically assigning or removing a permission set group, you can create a new record-triggered flow that invokes the autolaunched flow as a subflow. Build once, maintain once, leverage several times. #WorkSmartNotHard.

Now, it’s your turn. Automate the process for assigning/removing permission set groups in your org today!

Resources

Flow Enhancements Summer '24.

Flow Enhancements | Summer ’24 Be Release Ready

Summer ’24 is almost here! Learn more about new Flow Builder enhancements like the Automation App, Action Button (beta), and more, and check out Be Release Ready to discover more resources to help you prepare for Summer ’24.  Want to see these enhancements in action? Salesforce product manager Sam Reynard and I will demo some […]

READ MORE
A Salesforce Admin's Guide to TrailblazerDX 2024.

A Salesforce Admin’s Guide to TrailblazerDX 2024

The Trailblazer community is coming back together on March 6-7, 2024, in San Francisco and on Salesforce+ for TrailblazerDX 2024—join us! Generative artificial intelligence (AI) is revolutionizing application development, creating the most significant shift and opportunities for both admins and developers in decades. At TDX, you’ll learn to supercharge user productivity, automate business processes, and […]

READ MORE
Be Release Ready Spring '24 | The Ultimate Guide to Prompt Builder.

The Ultimate Guide to Prompt Builder | Spring ’24

Artificial intelligence (AI) is not a new concept to Salesforce or to Salesforce Admins. Over the years, Salesforce has empowered admins with a user-friendly interface for the setup and configuration of predictive AI features such as Opportunity Scoring, Lead Scoring, Einstein Bots, and more. The introduction of generative AI in Salesforce brings even more possibilities […]

READ MORE