Salesforce: Who Has Permission? (And what Profiles/Permission Sets Grant It?)

“Can you run me a report to see who has edit permissions on Cases?”

It’s the kind of thing that makes you cringe since it’s such a simple question and not remotely easy to achieve since the config screens are a disaster and it could be in any number of Profiles or Permission Sets.

Here’s how to find out. The following query will give you a quick list. (H/T Adam Torman)

SELECT Assignee.Name
FROM PermissionSetAssignment
WHERE PermissionSetId
IN (SELECT ParentId
FROM ObjectPermissions
WHERE SObjectType = 'My_Object__c' AND
(PermissionsCreate = true OR PermissionsEdit = true))
and Assignee.isActive = true

You can run this in the Developer Console under “Query Editor” tab.

Note that you have to change “My_Object__c” to your object name, and this filters by active users and Create or Edit permissions. You can run this using Workbench, dump it to Excel and deduplicate it. Problem solved.

Great. So What Profiles/Permission Sets Grant Access?

So the next question is going to be, OK, what profiles or permission sets grant that access?

This gets a little tricky because Profiles actually use Permission Sets under the hood. So when you use the above query, you are looking at Permission Set Assignments related to Users, including those assigned via a Profile. This is a little confusing. It’s driven by the isOwnedByProfile flag on PermissionSet – if the flag is true, it’s a hidden Permission Set that underpins a Profile.

So basically you need to do this twice: first, find the Profiles that include an underlying Permission Set (isOwnedByProfile = true). Then find the regular Permission Sets.

You can run the following Apex in the Anonymous Window. (If you’re not technical, don’t be scared, it’s just Your Name -> Developer Console -> Debug -> Execute Anonymous.)


List<PermissionSetAssignment> pa = [SELECT Assignee.ProfileId, PermissionSet.ProfileId, Assignee.Profile.Name
FROM PermissionSetAssignment
WHERE PermissionSetId
IN (SELECT ParentId
FROM ObjectPermissions
WHERE SObjectType = 'My_Object__c' AND
PermissionsEdit = true)
(PermissionsCreate = true OR PermissionsEdit = true))
and PermissionSet.isOwnedByProfile = true];
    
Set <Id> paIds = new Set<Id>();
for (PermissionSetAssignment thisPa : pa)
    paIds.add(thisPa.Assignee.ProfileId);

List <Profile> profiles = [Select Name, Description from Profile where Id in :paIds];
for (Profile thisProfile : profiles)
    System.debug('Profile: ' + thisProfile.Name);

This will (inelegantly) output all the Profiles that grant the permission you’re looking for. (To see the output, go to Logs tab in the Dev Console, open the topmost Log, and check the box that says “Debug Only.”)

Finally, you can check the regular Permission Sets that contain the privilege by using this query:

SELECT PermissionSet.Name
FROM PermissionSetAssignment
WHERE PermissionSetId
IN (SELECT ParentId
FROM ObjectPermissions
WHERE SObjectType = 'My_Object__c' AND
(PermissionsCreate = true OR PermissionsEdit = true))
and Assignee.isActive = true
and PermissionSet.isOwnedByProfile = false

Dump to Excel and dedup.

It’s an ugly solution but it should be enough to answer the question when it’s asked.

Leave a Reply

Your email address will not be published. Required fields are marked *