Why we should use Custom Permissions

Mathieu Demuynck
Texeï
Published in
7 min readJun 28, 2018

--

When you’re wondering : “What should I do to give access to that custom button for some users ?” or “What should I do to bypass this Validation Rule for some users ?” and you can’t do it with the standard data security access, you think about a checkbox in User Object or the Hierarchical Custom Settings or a Custom Label but we forgot since release Winter 15 Salesforce has added the Custom Permission feature. Why we should use it ?

Let’s talk about the data access

Before I introduce the Custom Permission feature, I would like to summarize briefly how Salesforce manage the data access level by giving you useful links and best practices.

When I’ve begun to work on Salesforce the best way for me to learn about the data security and application security was the implementation of the recruiting application in the Force.com Fundamentals Book. Yes ! It was a book ! A part of this training is available from this TrailHead badge. It helps to understand the concept of Role, Sharing Rules, Hierarchy, Profile and Permission Sets with an explicit example. I encourage you to discover this training.

It is not easy to have a good overview of the data security management in Salesforce. So, I think the best way to explain and summarize the mechanism is by a diagram. Thanks to Paul Cooper for making this good diagram below :

It is essential to understand how the Salesforce data security is working but it is also important to mention the main best practices:

Simple is beautiful. Start with the company chart, understand the company desired sharing settings and keep the hierarchy as simple as possible and group roles together based on the necessary access level to data based on sharing rule requirements. Use a minimum of profiles, they should be linked to the job (Sales, HR, Service client) and the Permission Sets should be linked to the function or responsibility (Sales Manager, Sales Assistant, HR Manager…). Following this practice will allow you to keep the number of Profiles and Roles low.

Prefer to open doors, rather than to close them. A user should have one profile and one role (optional, but strongly recommended). In Salesforce, you can’t deny a permission with a sharing rule or a permission set. Beyond that baseline, you can’t cause conflicts if a user has more than one permission set or sharing access. But a strategy based on opening doors offers a better level of security. By default, no records or features should be accessible, authorization is given to certain users for certain features or records. The opening doors strategy will limit weaknesses and will facilitate their detection. If the administrator forgets to authorize a feature, the user will not be able to use it and will immediately signal support. In contrast, if the administrator forgets to close a door, a user can access a sensitive feature and be a security risk. These vulnerabilities are difficult to detect, because the user does not realize or does not want to flag it. These breaches can then multiply and continue for a long time before admin teams detect them. So, the best practice is to set the minimum of rights to the Profile and OWD and use Role Hierarchy, Sharing Rules and Permission Sets to open the doors.

Try to be generic. Try to create permission sets in a way that you can reuse them. Think about if you really need all of them. For example, maybe all your users have CRUD access to Account, so you don’t really need to create 4 Permission Sets for each Account action, one would be enough.

There are a lot of articles, blog and videos which explain how to use the data security model and some ways to manage and monitor the settings. I’ve listed some of them in the additional informations section, above the article. [1]

How can I control the access rights?

So, in Salesforce, Role and Sharing or Profiles and Permission Sets include built-in access settings for many entities, like objects, fields, tabs, and Visualforce pages. Role should follow the company hierarchy, we should have a few profiles and grant access with Role Hierarchy, Sharing rules and Permissions Sets. But, many features require access checks which users can access. Permission Sets and Profiles don’t include access for these custom processes and we need more granularity to manage the access rights in custom or standard developments, without changing the codebase.

How can I do it in Salesforce ?

This table list the « global variables » associated to Salesforce features which I have seen during my Salesforce developer experience in Trigger, Apex class, Validation Rules, Apex controller, VisualForce or Formula to control the access rights.

Which one is the best to manage specific access ?

I’ve classified them by from 1 (the worst) to 5 (the best). From my point of view, Role and Profile are not optimal. You could have a code looks like this :

UserRole role = [Select DeveloperName From UserRole Where Id = :UserInfo.getUserRoleId()];If (role.DeveloperName in (’Sales Manager’, ’Marketing Manager’)) {   Do something;}

or

Profile pr = [Select Name From Profile Where Id = :UserInfo.getUserRoleId()];if (pr.Name in (’Sales’,’HR’)) {   Do something;}

Role or Profile names should not be hardcoded and be set in a Custom Label. So, for example, if the Marketing user asks me for giving access to the functionality I could add his role in the Custom Label. But I don’t want to give the access to all users who have that role and I can’t give a new role to the user, because in Salesforce a user can only have one Profile and one Role.

So, it is better to have a code looks like :

Hierarchy__c CS = Hierarchy__c.getValues(UserInfo.UserId());if (CS.canCloneCase__c) {   Do something;}

If a user has to clone a case, I will assign him the permission from the Custom Settings.

So, the best choice seems to use the Hierarchical Custom Settings. If you want to learn more about Hierarchical Custom Settings you can go to the Jitendra Zaa’s blog.

What’s about the Custom Permissions ?

Custom permissions let you define access checks that can be assigned to users via permission sets or profiles, similar to how you assign user permissions and other access settings. You can:

  • enable Custom Permissions in Profiles
  • enable Custom Permissions in Permission Set
  • define dependencies between your Custom Permissions
  • assign Custom Permission to users
  • determine what custom permissions users have when they authenticate in a connected app from the user’s Identity URL
  • determine which users have access to specific custom permission with the global variable $Permission in a Formula or Validation Rule
  • determine which users have access to a specific custom permission, using an SOQL query with the SetupEntityAccess and CustomPermission sObjects. The query is:
SELECT Id,
DeveloperName,
(SELECT SetupEntityId
FROM SetupEntityAccessItem
WHERE SetupEntityType=’CustomPermission’
AND ParentId IN (SELECT PermissionSetId
FROM PermissionSetAssignment
WHERE AssigneeId=:UserInfo.getUserId()
)
)
FROM CustomPermission

And since the Winter 18, there is new FeatureManagement Class and its method checkPermission to check whether a custom permission is enabled in Apex without use a SOQL query.

The code looks like:

if (FeatureManagement.checkPermission(‘cloneCase’)) {   system.debug(‘cloneCase permission is enabled for me’);}

Try it yourself in an anonymous Apex script. It’s working fine without usage limits !

10:34:56.36 (36399720)|EXECUTION_STARTED
10:34:56.36 (36406208)|CODE_UNIT_STARTED
[EXTERNAL]|execute_anonymous_apex
10:34:56.36 (37856093)|USER_DEBUG|[2]|DEBUG|cloneCase permission is enabled for me
10:34:56.37 (37926128)|CUMULATIVE_LIMIT_USAGE
10:34:56.37 (37926128)|LIMIT_USAGE_FOR_NS|(default)|
Number of SOQL queries: 0 out of 100
Number of query rows: 0 out of 50000

Number of SOSL queries: 0 out of 20
Number of DML statements: 0 out of 150
Number of DML rows: 0 out of 10000
Maximum CPU time: 0 out of 10000
Maximum heap size: 0 out of 6000000
Number of callouts: 0 out of 100
Number of Email Invocations: 0 out of 10
Number of future calls: 0 out of 50
Number of queueable jobs added to the queue: 0 out of 50
Number of Mobile Apex push calls: 0 out of 10
10:34:56.37 (37926128)|CUMULATIVE_LIMIT_USAGE_END
10:34:56.36 (37973355)|CODE_UNIT_FINISHED|execute_anonymous_apex
10:34:56.36 (39148807)|EXECUTION_FINISHED

The new line in the table is:

I give it the number 5 !

From my point of view, Custom Permission is the new best feature to control dynamically in custom or standard dev the user’s permissions for custom apps or processes. It will be fine if we could assign the Custom Permission to a public group (vote for the idea). I invite you to read this Andy’s article blog to have more explanation about the Custom Permission configuration.

Moreover, Salesforce suggest using Custom Metadata instead of List Custom Setting. Perhaps, in the future Salesforce will suggest to use Custom Permission Sets instead of Hierarchical Custom Setting ;-)

--

--