I often get the following question from administrators, “now that a user can have multiple permission sets in addition to their profile, how can I tell what permissions they have?”

It makes sense, after all: a user’s permissions determines their right to do almost anything in an org. For compliance and troubleshooting reasons, it’s important to be able to track down why a user has a certain access right and correct it if need be.

Summer ’12 introduces the ability to answer this question using the permission set API. We’ve created a new field on the PermissionSet SObject called IsOwnedByProfile. This field determines whether a permission set is a custom one or if it is parented by a profile. This is made possible because for every profile, there is one underlying permission set. That way, permissions layer equally across permission sets without having to treat a profile differently. In the setup user interface, you only see the profile but in the API, you can see both the profile and the underlying permission set.

As a result, running the following query in SOQL will return both permission sets you’ve created and permission sets parented by a profile:

SELECT Id,IsOwnedByProfile,Label
FROM PermissionSet

By adding IsOwnedByProfile to the WHERE clause, you will quickly differentiate between permission sets you’ve created versus those parented by a profile:

SELECT Id,IsOwnedByProfile,Label
FROM PermissionSet
WHERE IsOwnedByProfile = TRUE

Once you have the hang of this, you can start to answer all sorts of questions about your users such as, “which users have Read on Accounts and why”:

SELECT Assignee.Name, PermissionSet.Id, PermissionSet.isOwnedByProfile, PermissionSet.Profile.Name, PermissionSet.Label
FROM PermissionSetAssignment
WHERE PermissionSetId
IN (SELECT ParentId
FROM ObjectPermissions
WHERE SObjectType = 'Account' AND
PermissionsRead = true)

You might need to answer questions about a specific user such as, “what are all of the Account fields where John Doe has at least Read access and why”

SELECT Id, SObjectType, PermissionsRead, Parent.label, Parent.IsOwnedByProfile
FROM ObjectPermissions
WHERE (ParentId
IN (SELECT PermissionSetId
FROM PermissionSetAssignment
WHERE Assignee.Name = 'John Doe'))
AND
(PermissionsRead = true)
AND
(SobjectType = 'Account')

Using permission sets in this way, you can find out why a user has access to an apex page, class or a particular user, object, or field permission, regardless of whether it’s through their profile or permission set.

These SOQL queries are great if you have one off questions about your user’s permissions. If you have a more regular need to query user’s permissions, think about creating a Visualforce page with an Apex controller that uses these queries to find out what your users can do and why.

tagged , , , , , Bookmark the permalink. Trackbacks are closed, but you can post a comment.
  • http://twitter.com/Jai_SinghG JAI SINGH

    Wav Great…

  • Ron Hess

    Bingo !!, i needed that, Thanks Adam!

    • Adam Torman

      Glad it worked out Ron! Check out salesforcehacker.com for more permission set SOQL Tips.

  • clSFDCStudent

    Adam, Thank you for really helpful guide here!!

    I do have a quick question though. Is it possible to assign a ‘permission set owned by a profile’ to another profile?
    ‘Edit Assignment’ from Profile page doesn’t list these permission sets that are listed after the second SOQL described in the article.

  • Tyler Mowbrey

    Question: How do I query for all users who have access to manage public list views? This does not seem to be a field on the permissionset object which leads me to believe that I am not getting a full view of all security permissions.