Salesforce Permissions Design

Define a convention for Profiles, Permission Sets and Custom Permissions that describes which one to use for, what's their expected content and what's their expected naming convention. This document doesn't cover the record level security aspect of the platform (with / without sharing, groups, sharing settings and so on).

Problem Description

Permissions are a maintenance nightmare right now. Our existing profiles-for-all system is unflexible and fragile. It is hard to know the reasons why certain users have access to certain fields, objects or features or whether we need to grant permissions to what users and why. This not modular at all, so having more granular permissions for the same profiles is not possible.

As we know this is a consequence of using a profile-only-based-security, so we have moved into creating permission sets and custom permissions instead. Whereas this resolves some of the above problems, the prominent growth of these two items introduces a new one that is the absence of documentation or convention for them so it is extremely hard to know their intention with that lack of documentation or naming.

Background

Till the moment, all new permissions to objects, fields, classes and features have been granted or controlled through profiles and sometimes by layouts. That lead us to having a hard to maintain (insecure) security environment. It is not only hard to review and reduce permissions and be sure we are not breaking a flow, but also it is almost impossible to know why a user need a specific field and how it is related to a feature.

This is usually happens, even more in the Salesforce community as we didn't have a security mechanism other than profiles till relatively recently when they delivered Permission Sets. The convention we have followed is that there is no convention. Is the product owner defining what the user needs and we assigning permissions through profile to the affected folks.

Nowadays we have more tools in the platform to avoid the above problems. This document describes the conventions for generating new and granting permissions to users.

Solution

What permissions to assign

The number one rule is to assign the minimum possible permissions to all users.

  • If it is not expected a user to see an object or a field, don't assign it to them.
  • If some data has to be shown in a custom page (aura or LWC), but the user doesn't necessarily have to visit the record/data in a native page. Don't grant permissions to them.
  • If they have to see an object or field in a native page but not necessarily edit it, give read only permissions.
  • If they have to see an object or field in a native page, and it is the code that handles the edit, the same as above. Give them read only permissions.
  • If they have to edit a field in a native page, grant edit permissions only to the fields under this requirement.
  • If they have to be able to delete a record, first consider if it has to be controlled by a flow. If there are no dependencies or flow requirements, grant them delete permissions.

How to structure the permissions

In an ideal world, all internal domain users should have the standard profile and then admins would be incrementally adding permissions using other mechanisms. Apart from that there would be a minimal number of admin users, plus any number of communities and API ones.

As mentioned it is not the reality, but it is fine as far as we grow properly and progressively move to a better design. So, from now on we'll think on crafting good Permission Sets instead of extending profiles.

Before describing how, there is an extract from Salesforce Lightning Platform Enterprise Architecture book about the design of permission sets that can serve as a good guidance:

"Think features, not roles: Do not be tempted to fall back to expressing the roles you envisage your application's users being assigned. Enterprise organizations are large and complex; rarely does one size fit all. For example, a team principle can have many different responsibilities across your application from one installation to another. If you get this wrong, the administrator will be forced to clone the Permission Set, resulting in the start of the proliferation of unmanaged Permission Sets that do not track with the new or changed functionality as your package is upgraded."

It is important to mention that Permission Sets are not a silver bullet. We still need to grant/deny permissions to features and if they are too granular it'd be hard to assign. Thus, we will be orchestrating the permissioning task through the following four elements:

  • Profiles
  • Permission Sets
  • Custom Permissions
  • Permission Set Groups

1. Profiles

Users must have a profile. We'll use them as the base line, and we will not extend them by default. The only legitimate reasons to have and maintain a profile are:

  1. Remove a reference of a deleted class/file/object...
  2. Add a reference to a field that replaces an existing one for the same feature unless there is permission set grouping fields for the given functionality.
  3. To contain system related permissions that are not part of a feature of us.
  4. To assign page layouts and lightning pages to group of users.
  5. For exceptional use cases they can also be used to contain Custom Permissions. That decision will be under the diligence of the team crafting the solution and a good documentation must be accompanied.

2. Permission Sets

Permission Sets will group access to fields and classes (@AuraEnabled) related to a specific feature. Also, they will serve as the vehicle of custom permissions. For instance, to perform a "Submit to Onboarding" operation, there will be a Permission Set containing access for:

  • The account fields needed to complete the KYC form on read only mode.
  • The KycOnboardingController.
  • A custom permission with a self-describing name (more on this in the next section).

3. Custom Permissions

Custom Permissions themselves doesn't extend any capability to the end users. They conform a semantic mechanism for us to know our intention to give a user access to non schema related operations. In plain English: Custom Permissions tell us if a user should be able to click a button.

In the Submit to Onboarding example above, if the user doesn't have a specific custom permission, we could hide the KYC form or fail gracely with a "You are not allowed to perform this operation." pop-up message.

Custom Permissions will be added to their corresponding Permission Set so that they can be properly assigned. Exceptionally and for edge cases, they can be directly assigned to profiles at the discretion of the team designing it, but it has to be properly documented.

4. Permission Set Groups

Whereas permission sets provide a fine-grained mechanism to architect and assign our permissions, it is hard to assign when there are too many (and there will be). The truth is that there are operations that are expected to be available together. To simplify the assignment, the permission set groups came to rescue.

They are just a way to group sets of permission sets. Although they also allow specifying extra permissions by themselves, we will use them for their main purpose which is group permissions.

Again, in the Submit to Onboarding example, a Permission Set Group could contain the PS specific for this along with one designed to allow a Lead Qualification as they will be part of the same flow.

How to describe permissions

Background

To not create a bigger problem than the one with the current permissions approach, our elements above have to convey cristal clear what are their intention. We will achieve that by:

  • Selecting a good naming convention.
  • Providing a rich description with the future admin in mind.
  • Documenting these permissions elsewhere (TBD).

For the naming, and getting back to the Salesforce Lightning Platform Enterprise Architecture reference:

"Naming convention: When the administrator is viewing your Permission Sets in the Salesforce UI, ensure they are grouped according to the functional aspects of your application by considering a naming convention ..."

At the moment, the features and areas of our application have been distributed among "squads". These squads are essentially in charge of functional aspects of the business. You might understand this groups as the roles we have in the company, but they actually define "contexts", so be careful to no confuse the terms when defining permissions.

We have:

  1. Sales & Dealing
  2. Onboarding
  3. Finance

Inside them we have several features like Exceptions, Fees, Odd, and so on. To be accurately assigning permissions to users we have to use that slicing of the product.

The actual naming convention

  • Permission Sets: Will be defined as Area or Context - Feature - Operation on capital letters. E.g. Onboarding - Screening - Screen Account. The API name and thus the file name must be CamelCasedAreaOrContext_CamelCasedFeature_CamelCasedOperation. E.g. API Name = Onboarding_Screening_ScreenAccount, File Name = Onboarding_Screening_ScreenAccount.permissionset-meta.xml.
  • Custom Permissions: Will be defined as Operation or when there is an opportunity to confusion Operation (Feature or Object), both on capital letters. Eg: Screen (Account) to access to screening in the account detail page and Screen (Contact) for the contact one. The API Name will be CamelCasedFeature or whenever it might cause confusions CamelCasedFeature_CamelCasedOperation. Eg: API Name = Account_Screen, File Name = Account_Screen.customPermission-meta.xml. The reason why the label and API are different, is because in the UI will be easier to find permissions sorted by feature name, but for devs will be easier to handle if we see all feature permissions next to each other.
  • Permission Set Groups: Will be defined as Area or Context - Feature Management on capital letters. E.g. To group all screening Permission Sets: Onboarding - Screening Management. Now, the API name must be CamelCasedAreaOrContext_CamelCasedFeatureManagement. E.g. API Name = Onboarding_ScreeningManagement, File Name = Onboarding_ScreeningManagement.permissionsetgroup-meta.xml.

Alternatives

Didn't find any.

Caveats

Although it would be good to apply a homogeneous structure to the whole product, we are not meant to rework everything in bulk. This will be tackled progressively when time allows. The conventions here should apply to new features or ones that exist and make sense to separate.

Operation

Everyone in the team (not only devs) will be responsible for defining, describing and documenting the permissions as we go.

Security Impact

This will help to reduce the users over-permissioning apart from ensuring a good domain division.

Performance Impact

Checking lot of permissions instead of just one might have an impact on CPU usage. Our users have a relatively small scope, so it shouldn't be affected by the platform performance. However, we have to be aware of that and assign the users the appropriate level of access that group most of their usual activities.

Developer Impact

On the one hand, it will be progressively easier to remove references from code and reduce opportunities from git conflicts among other benefits.

On the other hand, it will require devs to get used to this and will sometimes generate doubts on how to craft them. This is a matter of time though and it is not expected to slow down developments.

Data Consumer Impact

There will be a documentation in place to instruct admins how to onboard users and to maintain their permissions.

Deployment

This has to be done progressively. We won't do a migration of the existing permissions. It is expected though, the team to be moving resources from profiles to the above architecture whenever makes sense.

Dependencies

N/A

References