Advertisement

Security & Sharing

Permission Sets vs Profiles — Salesforce Migration Guide (2026)

Published 11 June 2026 · 12 min read · Intermediate

Permission sets vs profiles is no longer a style debate — it is a migration with a deadline of practicality. Salesforce’s access model has been permission-set-led for years now, new features increasingly ship with permission-set-only switches, and orgs still running thirty cloned profiles are paying for it in audit time, deployment conflicts and onboarding friction. This guide covers what actually remains on the profile in 2026, how to structure permission sets and groups, and the migration sequence that doesn’t break user access mid-flight.

This sits inside the wider Salesforce security model — permissions answer what a user can do; record-level sharing answers which records they can do it to. Don’t conflate the two during the migration.

Where the EOL story actually landed

Salesforce originally announced the end of permissions on profiles, then retired the hard deadline after customer feedback. The destination did not change — only the enforcement. The supported model in 2026:

  • Profile — one per user, reduced to a minimal container
  • Permission sets — all functional access, stackable, additive
  • Permission set groups — persona-level bundles with optional muting

New platform capabilities increasingly expose their access switches only as permission set toggles. Every release makes the profile-heavy org slightly more stuck. That, not a deadline, is the forcing function.

What stays on the profile — the complete list

After full migration, the profile legitimately owns four things:

SettingWhy it can’t move
Login hoursProfile-only setting, no permission set equivalent
Login IP rangesProfile-only setting
Default record typeDefaults are a profile concept; record type access moves to permission sets
Page layout assignmentAssigned per profile + record type

Everything else — object CRUD, field-level security, app visibility, tab settings, Apex class access, Visualforce page access, custom permissions, system permissions, connected app access — belongs in permission sets. A correctly migrated org has profiles you can count on one hand: typically a Minimum Access baseline for humans, plus the special-purpose standard profiles you cannot delete.

Design rules for permission sets that scale

The migration fails when teams convert thirty profiles into thirty mega permission sets — same mess, new container. The structure that works:

1. Permission sets are capabilities, not personas. Name them for what they grant: Opportunity_Edit, Invoice_Admin, API_Access, Reports_Builder. A permission set with a job title for a name is a profile in disguise.

2. Permission set groups are personas. PSG_Sales_User = Opportunity_Edit + Quote_Create + Reports_Builder. One persona, one group, one assignment. When the Sales persona gains a capability, you add one permission set to one group and every assigned user gets it.

3. Muting is the exception tool, not the design tool. A muting permission set inside a group subtracts specific permissions from the group’s total — built for “Sales User, but this subset can’t delete.” If you find yourself muting heavily, your capability sets are cut too coarse.

4. Session-based permission sets cover elevated access that should exist only during an authenticated session context — worth knowing, rarely your first problem.

The additive rule underpins everything: a user’s effective access is the union of profile + all permission sets + all groups, minus mutings. Nothing in a permission set ever takes access away. If something must be removable per-user, it must be granted granularly enough to be unassignable.

The audit — SOQL before strategy

You cannot migrate access you haven’t inventoried. Three queries do most of the work.

What grants access to a given object:

SELECT Parent.Name, Parent.IsOwnedByProfile, Parent.Profile.Name,
       PermissionsRead, PermissionsCreate, PermissionsEdit, PermissionsDelete
FROM ObjectPermissions
WHERE SobjectType = 'Invoice__c'
ORDER BY Parent.IsOwnedByProfile DESC

Parent.IsOwnedByProfile = true rows are your migration backlog — each one is a grant living on a profile that needs a permission-set home.

Who holds a given permission set:

SELECT Assignee.Name, Assignee.Profile.Name, PermissionSet.Name
FROM PermissionSetAssignment
WHERE PermissionSet.Name = 'Opportunity_Edit'

Which profiles still carry dangerous system permissions:

SELECT Name, PermissionsModifyAllData, PermissionsViewAllData,
       PermissionsAuthorApex
FROM Profile
WHERE PermissionsModifyAllData = true OR PermissionsViewAllData = true

Run these into a spreadsheet and you have the real scope of the migration — usually smaller than feared, because most cloned profiles differ from each other in a handful of rows.

Migration sequence — grant first, strip last

The order is the whole risk model. Per persona:

  1. Build capability permission sets from the audit of that persona’s profile
  2. Compose the permission set group for the persona
  3. Assign the group alongside the existing profile — access is additive, so nothing breaks
  4. Verify with User Access Summary on representative users: every permission should now show a permission-set source in addition to the profile source
  5. Strip the profile of the migrated permissions
  6. Re-verify the same users — effective access must be identical, now sourced purely from the group
  7. Re-point the user to the minimal baseline profile

Never invert steps 3 and 5. Stripping before granting is the migration pattern that generates the “nobody can see Opportunities” incident, and it always happens at 9am on a Monday.

Two populations need special handling: integration users belong on the Salesforce Integration license with narrow API permission sets rather than inheriting a human persona, and admins should keep their own thin group so that admin access is auditable like everything else.

Pitfalls that surface mid-migration

  • Field-level security drift. FLS lives in both profiles and permission sets; during coexistence (steps 3–4) a field visible via the profile but missed in the permission set passes verification, then vanishes at step 5. Diff FLS explicitly, don’t eyeball it.
  • Record type access vs default. Access to record types moves to permission sets; the default record type stays on the profile. Migrate access, keep the default, or users get a record type picker with no default selected.
  • Deployment coupling. Profiles in change sets and metadata deployments are notoriously partial; permission sets deploy cleanly and completely. This alone repays the migration — see how this interacts with your deployment strategy if profiles have been corrupting your pipelines.
  • License mismatches. A permission set carrying a permission unsupported by a user’s license fails assignment at runtime. Audit license types before composing groups, not after.

The end state worth aiming for

Five or fewer profiles. Capability-named permission sets in the dozens, not hundreds. One group per persona. Every access question answerable by one SOQL query, every access change deployable without touching a profile, every new hire onboarded with a single group assignment. Orgs that reach this state stop talking about permissions — which is the entire point.

Test your knowledge — Security & Sharing

10 questions · Basic to Advanced

0 / 10 correct

Advertisement

Frequently asked questions

Are Salesforce profiles going away?

No. Salesforce retired the original hard end-of-life plan; profiles remain, but as a minimal container. The supported direction is permission-set-led access, where profiles hold only what cannot live anywhere else.

What is the difference between a profile and a permission set?

A user has exactly one profile but any number of permission sets. The profile defines baseline settings like login hours, login IP ranges and default record types; permission sets grant the actual functional access — object, field, Apex class and system permissions — additively on top.

What should remain on the profile after migrating to permission sets?

Only the settings that cannot move: login hours, login IP ranges, default record type selection, and page layout assignment. Every object, field, app, Apex class, Visualforce page and system permission should be granted via permission sets.

What is a permission set group in Salesforce?

A bundle of permission sets assigned as a single unit, typically mapped to a job persona like Sales User or Support Supervisor. Groups support muting permission sets, which subtract specific permissions from the combined grant.

How do I find which permission sets grant access to a specific object?

Query ObjectPermissions filtered by SobjectType. The Parent relationship resolves to the owning permission set or profile, so one SOQL query gives a complete access inventory for any object.

Can a permission set remove a permission a profile grants?

No. Permission sets are purely additive — they can only grant, never revoke. The only subtractive mechanism is a muting permission set inside a permission set group.

Advertisement