This blog post is written by Eric Kintzer, Salesforce Architect at Helix, and Gearset Community Advisor.
For several years, Salesforce has signalled that orgs should move away from profiles and towards permission sets. Following their recent announcement that permissions on profiles will be retired in Spring ‘26, moving away from profiles has become even more pressing. This article looks into some of the implications of making that transition, as well as a step-by-step migration strategy.
What’s the difference between profiles and permission sets?
Profiles, permission sets, and permission set groups are among the primary ways that Salesforce manages user access to your application’s functionality.
PermissionSetGroup are all metadata types that can be deployed between orgs and/or source control with a DevOps tool such as Gearset.
Currently, a profile is a collection of permissions, which can range from CRUD (create, read, update, delete) access permissions to permissions for specific object types and fine-grained functionality such as Manage Public Folders.
A permission set is also a collection of permissions, but, unlike profiles, permission sets can be extended to give users functional access without making a change to their profile.
It’s important to remember that profiles and permissions define field-level access, field-level security (FLS) and object-level or CRUD access, but don’t define which records of a given object the user can view or change. That is, a user may have permissions to view
Account objects, but which specific
Account records can be viewed is controlled by sharing rules. Sharing rules are not part of profiles or permission sets.
Profiles and their implications for DevOps
Profiles are tricky to manage, making them difficult to incorporate into a DevOps workflow.
As it stands, the metadata definition for a profile includes:
- Apex class access
- Application visibility
- Category visibility
- Custom tab visibility
- Custom metadata type access
- Custom permissions
- Custom setting access
- External data source access
- Field permissions (the big one, i.e. FLS)
- Layout assignments
- Login hours
- Login IP ranges
- Object permissions (the CRUD)
- Record type visibility
- User permissions (also large, as there are 100+)
- Visualforce page access
The retirement of permissions on profiles will drastically scale down the metadata associated with profiles and reduce the number of profiles needed.
Moving to permissions sets will make your deployments go faster, because there’s less metadata to consider. For example, if you just use Gearset’s default comparison filters, Default comparison or Default CI comparison, all of this profile metadata has to be retrieved from Salesforce and analyzed by Gearset. This includes all of the standard profiles, many of which you probably don’t even use, like Contract Manager or Standard User. Here’s where a custom metadata filter in Gearset can help you:
Profiles can also cause security concerns. SalesforceBen sums up a common issue:
“Profile management also has a nasty tendency to be driven by User complaints instead of top-down security design. Users often ask for new permissions based on their job description, but they almost never come back and tell an Admin to remove old permissions that they no longer need. The end result of this one-way street is that Profiles often grant too much access for too many Users.”
The trend in Salesforce development is to move to packages, and away from monolithic orgs containing a ‘happy soup’ of metadata. But as a profile typically contains many, many permissions, it is unlikely that any given profile can be compartmentalized into a specific package. Since SFDX-format version control has to slot all metadata into a folder structure by package, this makes deploying profiles more challenging in any kind of DevOps automated pipeline. You could end up with too many inter-package dependencies, which would defeat the purpose of packages altogether.
Permission sets are better tied to application function and, by inference, to app-aligned SFDX packages.
Use the fewest possible profiles. An ideal org would use only these profiles:
- System Administrator (or a clone of it, e.g. My Company - System Administrator)
- Minimum Access - Salesforce (or a clone of it, e.g. My Company - Minimum Access)
- Automatically created guest user and community profiles
Principle of least privilege
By starting with the ‘Minimum Access - Salesforce’ profile assigned to all but your admins, you adhere to an information security dictum known as the principle of least privilege. Any given user is extended only those permissions necessary to do their function, and no more. In Salesforce, this is done by creating permission sets and permission set groups, and then assigning these to the users with the ‘Minimum Access - Salesforce’ profile.
Permission sets are additive, which means you’re always granting additional privileges to the user’s base profile. Prior to the Summer ’20 release, you couldn’t remove permissions once granted to a user without editing the permission set. However, with Summer ’20, Salesforce added the option to mute permission set groups. In general, use this muting feature only if you need to, and long after you have migrated from profiles to permission sets — otherwise, you might find it tricky to figure out what permissions are actually assigned to a given user.
Naming and scope of permission sets
Profiles tend to be named after roles, e.g. Sales Manager, Sales Rep, Marketing Specialist. Don’t fall into the trap of naming your permission sets in a similar way to profiles.
In Salesforce Lightning Platform Enterprise Architecture, Andrew Fawcett recommends the following:
- Think features, not roles — so, something like Case Edit would be much better than, say, Service Agent
- Granularity — combine granular permission sets into larger Permission Set Groups
- Naming Conventions — think of major, intermediate and minor naming conventions because you’ll have lots of permission sets. That way, the permission sets can be sorted logically within the Salesforce admin user interface
Another useful suggestion from NimbleAMS is to normalize permission sets that reference objects. For example, a permission set for access to
Case should differ from a permission set with access to
Opportunity. Then, think more granular to create ‘Opportunity - Edit’ and ‘Opportunity - View’. There’s no one size fits all but, if you think granular, combining into higher level permission set groups becomes easier.
If you have an existing org with many (or many, many) profiles, a good place to start would be collapsing very similar profiles into one.
For example, you might have these profiles: Customer Service Agent and Customer Service Manager. These two profiles are probably very similar, differing only in a few extra permissions granted to the manager. Collapse these into one profile: Customer Service. Then create a permission set (or sets) to represent the extra privileges used by the Manager.
Use Gearset to help you with this analysis by clicking on the Explore permissions link for any given monitoring job’s execution:
You can also look up permissions for a specific field or object:
And you can view the individual permissions for profiles or permission sets:
Salesforce Labs also has a useful profile and permission set helper that allows you to convert profiles into permission sets.
Step-by-step migration of profiles to permissions sets
Here are suggested steps for migrating from profiles to permissions sets by using Gearset in a series of deployments:
- Create a new Customer Service profile with the core permissions needed by all staff in that department (you can’t use the Metadata API or Gearset to rename profiles).
- Create a new permission set(s) containing the functional privileges used by managers.
- Deploy the new permission set(s); assign the managers to the Customer Service profile and provision them with the new permission set(s).
- Delete and deploy the Customer Service Manager profile.
- Reassign all the agents to the Customer Service profile.
- Delete the Customer Service Agent profile and deploy.
- Create a permission set(s) for the core agent required privileges; deploy and assign to the agents.
- Reassign all customer service staff to the Minimum Access - Salesforce profile.
- Delete the Customer Service profile; and deploy.
You can combine some of these steps if needed, but they have the advantage of being stepwise, which means you can interrupt the migration at any point and still have a functional application. None of this will be fun — but the end result will be a modular, more secure, org.
While Salesforce recommends that orgs move to permission sets, the tools don’t always make it easy for admins. Here are some of the sticking points:
When adding new custom fields (a common task), the editor makes it easy to assign FLS for that field to profiles but offers no assistance to assign FLS to a permission set. You have to do this in another user interface transaction, which can be very easy to forget. On the plus side, it makes you think about which permission set truly needs FLS for your new field — thus making you more security conscious. Note that in Spring ‘23, Salesforce provides an option to expose the Permission Sets when creating a new custom field.
There’s no way to assign default page layouts by permission set, only by profile. If your application depends on this, why not vote up this idea? Classic admins can work around the limitation somewhat by collapsing page layouts into one per record type and using CRUD (for related lists) and FLS (for fields) to individualize the layout based on user need. Lightning Experience admins have this flexibility too, as well as dynamic Lightning Page components. Winter ‘23 added dynamic forms for certain standard objects (e.g. Account) and over time, more standard objects will get this capability.
Login IP restrictions and hours. If you have such an org, with different login policies, you’ll still need profiles for each use case.
A summary of what isn’t supported by permission sets can be found in the Salesforce User Permissions and Access documentation. Stay tuned to release notes for upcoming Salesforce versions.
Deploying permission sets with Gearset?
If you’re struggling with a deployment or would like some further advice on migrating from profiles to permission sets, read our blog post on how Gearset provides a better way to deploy profiles and permission sets. Our team of DevOps experts are always happy to help you in any way we can — just reach out to us via the live chat bubble on our website.
- Control Access to Objects (Trailhead)
- Discover the New World of Profile Management (AppExchange and the Salesforce Ecosystem)
- Profile and Permission Set Helper (Salesforce Labs)