Understanding the available security features

The platform provides security controls to manage the accessibility of functionalities in your application and also the visibility of the individual records it creates. As an application provider, your code has a responsibility to enforce security rules as well as to provide integrations that help administrators configure security easily. This section is not aimed at taking a deep dive into the security features of the platform, but is more an aid in understanding the options, best practices, and packaging implications.

One of the key checks the security review process described in the previous chapter makes is to scan the code to ensure that it is using the appropriate Apex conventions to enforce the security rules administrators of your application configure, as not all security checks are enforced automatically for you.

This chapter discusses the following two categories of security as provided by the platform:

  • Functional security: Security that applies to application objects and some code entry points (providing APIs) and also Visualforce pages that deliver the features of the application is referred to here as functional security
  • Data security: In contrast to security applied to individual record data created and maintained by the application, this type of security is referred to as data security

Functional security

Both profiles and Permission Sets can be created and packaged in your application to help administrators of your application control access to your objects, fields, tabs, and pages. Fundamentally, profiles have been historically used to prepackage the roles, such as team principle, you envisage users using in your application. In contrast, Permission Sets can be used to express the functionality in your application such as the ability to assign a driver to a race.

By now, most people are familiar with configuring profiles to control security. The issue is that they can eventually lead to a proliferation of profiles; as small differences in needs between users arise, profiles are then cloned and thus increases the administration overhead when performing common changes. To manage this, Salesforce created Permission Sets, which is a much more granular way of expressing security controls.

From an application perspective, you can package Permission Sets and even have them upgraded automatically as they change in accordance with the new or updated functionality in your application. You can also assign them after installation, in contrast to profiles, which can only be done during the installation. Also unlike profiles, administrators cannot edit them though they can clone them if there is a need (this is not possible in Professional and Group Editions of Salesforce). Because of these benefits, it is recommended that Permission Sets be used over profiles when packaging security information about your application.

It is important to plan your use of Permission Sets from the start so that your development team keeps them updated and their usage remains consistent throughout. Consider the following when designing your Permission Set strategy:

  • Think features not roles: Do not be tempted to fall back to expressing the roles you envisage your application 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.
  • Granularity: As you design the functionality of your application, modules are defined (you can use Application under Setup to indicate these), and within these objects, tabs, or pages, each has distinct operations. For example, the Contestant object might describe the ability to indicate that a driver has crashed out of the race and update the appropriate DNF field, which is Update DNF Status. For example, this permission might be assigned to the race controller user. In contrast, you might have a less granular Permission Set called Race Management, which encompasses the Update DNF Status permission plus others. Considering this approach to design your Permission Sets means that administrators have less work to assign to users, while at the same time, they have the power to be more selective should they wish to.
  • 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, for example, FormulaForce - Race Management and FormulaForce - Race Management - Update DNF Status.

Tip

One of the limitations of the License Management Application (LMA) described in the previous chapter is that it is not very granular; you can only effectively grant user licenses to the whole package and not modules or key features within it. With the introduction of Permission Set licenses, Salesforce looks to be heading down the path of providing a means to define your licensing requirements with respect to Permission Sets. At the time of writing this, there was no support for developers to create their own; this looks like the next obvious step. This is something to consider when designing your Permission Sets for use as license control, for example, one day you may be able to use this to enforce a pricing model for high-priced licenses associated with the Race Management permission.

Perform the following steps in the package org to try out this process:

  1. Create a Race Management custom application (under Setup | Create) and add the Driver, Season, and Race tabs created earlier to it; make the Race tab the default.
  2. Create a Race Analytics custom application and add the Race and Reports tabs to it; make the Reports tab the default.
  3. Create the Permission Sets for the FormulaForce application as shown in the following table. Leave the User License field set to None.
  4. Finally, add the following Permission Sets to the FormulaForce package.

Permission Set

Permissions

FormulaForce - Race Management

Race Management (Custom Application)

Race Analytics (Custom Application)

Season tab (Custom Tab)

Race tab (Custom Tab)

Driver tab (Custom Tab)

Object (Custom Object, Full Access)

Race object (Custom Object, Full Access)

Driver object (Custom Object, Full Access)

Contestant object (Custom Object, Full Access)

FormulaForce - Race Management - Update DNF Status

Contestant object (Custom Object, Read, Edit)

DNF (Custom Field, Read, Edit)

FormulaForce - Race Analytics

Race Analytics (Custom Application)

Race object (Custom Object, Read Only, Read DNF)

Here, Full Access means it gives access to read, create, edit, and delete all custom fields. Also, at the time of writing this, the Custom Application and Custom Tab components within Permission Sets are not packable. Until they become packable, it is recommended that you still maintain this information in the Permission Sets.

Your code and security review considerations

Not all code you write will automatically be subjected to enforcement by the platform through the object- and field-level security defined by the Permission Sets or profiles assigned to users. While certain Visualforce components such as apex:inputField and apex:outputField enforce security, other ways in which you obtain or display information to users will not enforce security, such as apex:inputText and apex:outputText. The differences will be discussed in more detail in a later chapter.

When your code is performing calculations or transformations on fields in the controller, expose this data indirectly via Apex bindings or remote action methods on your controller; for this, you need to add additional checks yourself. This also applies to any customer facing the Apex code such as global methods or Apex REST APIs you build.

In these cases, you can use the Apex Describe facility to specifically check the user's profile or Permission Set assignment for access and prevent further execution by returning errors or throwing exceptions. The formal reference information for implementing this can be found in the following two Salesforce articles:

The Salesforce security review scanner and team insist that you check Custom Object level security (CRUD security for short) and include checking for every field that is accessed (field-level security (FLS)).

Implementing code to check both needs careful consideration, planning, and monitoring. Implementing FLS is especially complex with multiple use cases and contexts applying different usage patterns within your code base. For some functionalities, you may wish the application to access certain objects and/or fields on the users' behalf without checking security; document these cases well as you might need to present them to Salesforce.

Implementing CRUD security is something we will revisit in later chapters on the Domain and Selector layers of your Apex code, where some automated support within the library used to support these patterns has been provided.

Tip

It's best to review and document your approach and use the CRUD and FLS checking as a part of defining your coding conventions, and if in doubt, discuss with your Salesforce Technical Account Manager (TAM) or by raising a support case in Partner Portal. This way, you will also have some reference decisions and conversations to use when providing input and background to the security review team. Meanwhile, the Salesforce community, including myself, is looking at ways of creating generic ways to enforce CRUD and FLS without having to see hardcoded checks throughout the code base.

Note that it is a common misconception that applying the with sharing keyword to your Apex classes will automatically enforce CRUD or FLS security, but it does not. This keyword solely controls the records returned when querying objects, so is in fact related only to data security.

Data security

Regardless of which Custom Objects or fields are accessible to the end user through their profile or Permission Set assignments, there may still be a requirement to filter which records certain users can see, for example, certain race data during and after the race can only be visible to the owning teams.

Salesforce allows this level of security to be controlled through the Owner field on each record and optionally a facility known as sharing. This is defined via the Sharing Settings page (under Security Controls | Setup), in the packaging org for the FormulaForce application. This page is shown in the following screenshot:

Data security

You can see the Standard Objects and also the Custom Objects we have created so far listed here. When you click on Edit, Default Access shows that the access options vary based on whether the object is a standard or Custom Object, as Salesforce has some special access modes for certain Standard Objects such as Price Book.

Tip

Notice that where an object is in a child relationship with a parent record, in the case of Race and Session, there is no facility to control the security of this object. Thus, when you are designing your application object schema, make sure that you consider whether you or your users will need to utilize sharing on this object; if so, it might be better to consider a standard lookup relationship.

For the Custom Objects that exist as a part of the FormulaForce application, you can define Public Read/Write, Public Read Only, and Private. The default value is always Public Read/Write.

The default access defines the starting position for the platform to determine the visibility of a given record using the Owner field and the object's sharing rules. In other words, you cannot use these features to hide records from a given user if the object has Public Read or Public Read/Write default access.

Tip

Although this setting is packaged with Custom Objects, it is editable in the subscriber org and is thus not upgradable. If you decide to change this in a later release, this will need to be done manually as a post-install task.

If you set the Private default access and do nothing, the Owner field determines the visibility of the records. By default, the owner is the user that created the record. Thus, users can only see records they create or records created by other users below them in the role hierarchy (if enabled). A record owner can be a user or a group (known as Queue within the API), for example, members of a specific racing team. Users can choose to manually share a record they own with other users or groups also.

Sometimes, a more sophisticated and dynamic logic is required; in these cases, sharing rules can be added and they can be created either declaratively (from the Sharing Settings page) or programmatically. Regardless of the approach used, the platform creates a Share object (for example, for a RaceData__c object, this would be RaceData__Share) that contains records resulting from the evaluation of sharing rules; these records can be queried like any other object, useful for debugging.

Tip

For the ultimate in flexibility, you can write logic within an Apex Trigger or Scheduled Job to directly create, update, or delete the sharing records, for example, in the RaceData__Share object. In this case, the criteria for sharing records can be practically anything you can express in code. You first define a sharing reason against the applicable Custom Object, which will be automatically included in your package. This is used as a kind of tag for the sharing records your application code creates versus sharing records created through sharing rules defined in the subscriber org. Also note that if the platform detects references to the Share object for a given object listed on the Sharing Settings page, it will prevent the subscriber org administrator from changing the default access from Private to Public.

Your code and security review considerations

The platform will enforce record visibility in cases where the user attempts to navigate to the record directly in the Salesforce UI, including reports they run and access provided via Salesforce APIs when they use third-party applications.

However, keep in mind that your Apex code runs at system level by default; thus, it's important to pay attention to the use of the with sharing or without sharing keyword (for all key entry points to your code). This is also something the security review scanner will look for. You might as well ask when using the without sharing keyword makes sense; such a use case might be when you explicitly want a system-level logic to see all records on behalf of an operation or validation the user is performing.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.163.13