Every so often we get a requirement from our customers to provide full visibility into the permissions in their Salesforce org. Salesforce is very flexible, allowing permissions to be assigned to users via their profile or via permission sets. While this allows a very flexible structure which can allow companies to assign the exact permission every user needs, it can become quite complicated to review.
Many companies need to export the permissions assignment for auditing which can become a difficult task. There is no native feature in Salesforce which provides one view of the permissions assignment, which in turn prevents the ability to export a list permissions externally.
We have written a script which trawls all the profiles in the Salesforce org. This covers all the permission sets and shows all the standard and custom permissions included with each profile and permission set along with all the users assigned to each profile or permission set. We can export this information to a CSV file.
Our export shows the permissions from profiles and permissions sets point of you. You can also create similar exports from a user point of view, to show all the permissions each user has, or from a specific permission point of view, to show all the users that have this permission.
We also didn’t export all the FLS and CRUD permissions just yet, we might extend our feature in the future to include them as well.
To run this script, use the Developer Console.
Click on the cog (or your name if you’re still using Salesforce classic) at the top right of your Salesforce screen and then click “Developer Console”. Then in the console go to the “Debug” tab and select “Open Execute Anonymous Window”.
Change your email in the first line of the script, copy and paste it into the popup window in your developer console and click Execute.
Enter the below:
<code>//Set your email String email_address = your@email.com'; Map> profiles_data = new Map>(); Map> permission_sets_data = new Map>(); //Get the standard permissions in each permission set Map standard_permissions_permissionset = new Map(); Schema.DescribeSObjectResult ps_describe = PermissionSet.sObjectType.getDescribe(); for(Schema.SObjectField ps_field : ps_describe.fields.getMap().values()){ Schema.DescribeFieldResult ps_field_describe = ps_field.getDescribe(); if(ps_field_describe.getName().startsWith('Permissions')){ standard_permissions_permissionset.put(ps_field_describe.getName(), ps_field_describe.getLabel()); } } //Query all permission sets with all their standard permissions List permissions_list = new List(standard_permissions_permissionset.keySet()); String query = 'SELECT Id, Label,' + String.join(permissions_list, ',') + ' FROM PermissionSet WHERE IsOwnedByProfile = false'; List permission_sets = (List)Database.query(query); Map permission_sets_name = new Map(); for(PermissionSet permission_set : permission_sets){ permission_sets_name.put(permission_set.Id, permission_set.Label); } //Query permission set assignments Map users = new Map([SELECT Id,Name,ProfileId FROM User WHERE IsActive = true]); List assignments = [SELECT Id, PermissionSetId, AssigneeId FROM PermissionSetAssignment]; Map permission_sets_map = new Map(); for(PermissionSetAssignment pas : assignments){ List user_in_ps = new List(); if(permission_sets_map.containsKey(pas.PermissionSetId)){ user_in_ps = permission_sets_map.get(pas.PermissionSetId); } if(users.containsKey(pas.AssigneeId)){ user_in_ps.add(users.get(pas.AssigneeId).Name); } permission_sets_map.put(pas.PermissionSetId, user_in_ps); } //Get the standard profile permissions Map standard_permissions_profile = new Map(); Schema.DescribeSObjectResult profile_describe = Profile.sObjectType.getDescribe(); for(Schema.SObjectField profile_field : profile_describe.fields.getMap().values()){ Schema.DescribeFieldResult profile_field_describe = profile_field.getDescribe(); if(profile_field_describe.getName().startsWith('Permissions')){ standard_permissions_profile.put(profile_field_describe.getName(), profile_field_describe.getLabel()); } } //Query all the profiles and their standard permissions permissions_list = new List(standard_permissions_profile.keySet()); query = 'SELECT Id, Name, ' + String.join(permissions_list, ',') + ' FROM Profile'; System.debug(query); List profiles = (List)Database.query(query); Map profile_name = new Map([SELECT Id, Name FROM Profile]); //Get custom permissions and their assignments to profile sand permission sets Map entity_id_to_custom_permissions = new Map(); List custom_permissions = [SELECT Id, DeveloperName, MasterLabel, (select Id, ParentId from SetupEntityAccessItems) FROM CustomPermission]; for(CustomPermission custom_permission : custom_permissions){ for(SetupEntityAccess entity_access : custom_permission.SetupEntityAccessItems){ List custom_permissions_list; if(entity_id_to_custom_permissions.containsKey(entity_access.ParentId)){ custom_permissions_list = entity_id_to_custom_permissions.get(entity_access.ParentId); } else { custom_permissions_list = new List(); } custom_permissions_list.add(custom_permission.MasterLabel); entity_id_to_custom_permissions.put(entity_access.ParentId, custom_permissions_list); } } //Prepare the data for every profile for(Profile p : profiles){ List profile_content = new List(); List standard_permissions = new List(); for(String standard_permission : standard_permissions_profile.keySet()){ Boolean permission_assigned = (Boolean)p.get(standard_permission); if(permission_assigned){ standard_permissions.add(standard_permissions_profile.get(standard_permission)); } } profile_content.add(standard_permissions); List custom_permissions = new List(); if(entity_id_to_custom_permissions.containsKey(p.Id)){ custom_permissions = entity_id_to_custom_permissions.get(p.Id); } profile_content.add(custom_permissions); List users_in_profile = new List(); for(User u : users.values()){ if(u.ProfileId == P.Id){ users_in_profile.add(u.Name); } } profile_content.add(users_in_profile); profiles_data.put(p.Id, profile_content); } //Prepare the data for every permission set for(PermissionSet p : permission_sets){ List permission_set_content = new List(); List standard_permissions = new List(); for(String standard_permission : standard_permissions_permissionset.keySet()){ Boolean permission_assigned = (Boolean)p.get(standard_permission); if(permission_assigned){ standard_permissions.add(standard_permissions_permissionset.get(standard_permission)); } } permission_set_content.add(standard_permissions); List custom_permissions = new List(); if(entity_id_to_custom_permissions.containsKey(p.Id)){ custom_permissions = entity_id_to_custom_permissions.get(p.Id); } permission_set_content.add(custom_permissions); List users_in_profile = new List(); if(permission_sets_map.containsKey(p.Id)){ users_in_profile = permission_sets_map.get(p.Id); } permission_set_content.add(users_in_profile); permission_sets_data.put(p.Id, permission_set_content); } //Write the profiles data String permissions_content = 'Profiles,,,\n'; permissions_content += 'Name,Standard Permissions,Custom Permissions,Users Assigned\n'; for(String profile_id : profiles_data.keySet()){ List profile_content = profiles_data.get(profile_id); if(profile_content.get(2).size() > 0){ permissions_content += profile_name.get(profile_id).Name + ',,,\n'; Integer lognest_list = Math.max(profile_content.get(0).size(),Math.max(profile_content.get(1).size(),profile_content.get(2).size())); for(Integer i = 0; i < lognest_list; i++){ permissions_content += ','; for(Integer j = 0; j < 3; j++){ if(profile_content.get(j).size() > i){ permissions_content += profile_content.get(j).get(i); } if(2 > j){ permissions_content += ','; } } permissions_content += '\n'; } permissions_content += '\n'; } } //Write the permissions sets data permissions_content += '\n\n\nPermission Sets,,,\n'; permissions_content += 'Name,Standard Permissions,Custom Permissions,Users Assigned\n'; for(String permission_set_id : permission_sets_data.keySet()){ permissions_content += permission_sets_name.get(permission_set_id) + ',,,\n'; List permission_set_content = permission_sets_data.get(permission_set_id); Integer lognest_list = Math.max(permission_set_content.get(0).size(),Math.max(permission_set_content.get(1).size(),permission_set_content.get(2).size())); for(Integer i = 0; i < lognest_list; i++){ permissions_content += ','; for(Integer j = 0; j < 3; j++){ if(permission_set_content.get(j).size() > i){ permissions_content += permission_set_content.get(j).get(i); } if(2 > j){ permissions_content += ','; } } permissions_content += '\n'; } permissions_content += '\n'; } //Email the export as a CSV file Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment(); efa.setFileName('permissions.csv'); Blob permissions_content_blob = Blob.valueof(permissions_content); efa.setBody(permissions_content_blob); Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage(); email.setSubject( 'Permissions Export' ); email.setToAddresses( new List { email_address } ); email.setPlainTextBody( 'Your permissions export' ); email.setFileAttachments(new Messaging.EmailFileAttachment[] {efa}); Messaging.sendEmail(new Messaging.SingleEmailMessage[] );</code>