The design of security rules can have an enormous impact on system responseness and scalability.
Relationship Security
Significant performance advantages can be achieved by judicious use of Security Relationships. Conversely, poorly configured security relationships can significantly impact performance.
Refer to Security Relationships for a list of best practices for configuring security relationships.
Security rules that relate to the current user
If any part of a report refers to 'current user', or if any of the security rules that apply to any part of the report refer to 'current user', then the results may change from user to user. This means that the cached report results cannot be shared across users, which can impact scalability.
Security rules that are optimised well by reports
A security rule will be detected as granting access to all records of a particular type 'T' if its report satisfies all of these conditions:
- The root node is not set to 'exact type only' in the advanced properties. (the default setting is the preferred setting)
- The report does not follow any relationships
- The report has no analyser conditions
- The root type of the report is either 'T' or an ancestor of 'T'
- The security rule itself applies to type 'T' or an ancestor of 'T'
While this is a pretty tight set of requirements, it's a fairly common scenario to say that (either for some roles or all roles), the user has access to all records of a particular type. For example, all users may have read permissions to see the record that represent departments or geographic locations so that they can select them in various forms. (But not necessarily the records that are associated with those departments or locations).
The ReadiNow reporting engine optimises this specific scenario.
A report is created for a particular object. However, most reports also follow relationships that lead to other objects (either in the report relationship tree, or by referring to them in calculations or calculated fields).
The reporting engine will determine all security rules that must be considered for all objects referenced in the report. However, if for a particular object, any of the rules are determined to satisfy the above conditions then reports know that it does not need to calculate and of the other security rules for that object - including ones that might be for inherited types.
However, this optimisation only applies if the security rule type is the same as, or a parent of, the node type. For example. if you have a relationship that points to records of the 'Person' object, and you have a rule that grants access to all 'Employee', then the optimisation cannot apply because it may be the case that some of the records linked by the relationship are of some type other than 'Employee', and therefore do not automatically receive access according to that security rule. If possible, consider tightening the relationship to only point to employee, or loosen the rule to grant access to all Persons. (Assuming of course that this makes sense for the rest of the business logic)
Make as many of these rules (that grant access to all instances of a type) as you can - and as broadly as you can.
Security rules apply to derived types
Security rules that do not grant access to all records of a type, however, also apply to derived types - and may even slow reports down.
For example, if a security rule says you can access a person if their email address contains @readinow, then that security rule will also apply to employees, customers, suppliers, or anything else that derives from person.
So make these rules apply to the tightest type possible. In this example, if you're only expecting the rule to only ever grant access to employees, then set employee as the rule type - so that way it can be ignored for other types.
If reports determines that a particular resource type has no rules that would grant access then it knows that the user can never see any records of that type, and will similarly optimise that case. However a stray rule applied to a parent type, such as the one above, would prevent this from happening.
Don't create general rules that apply to resource or editable resource. These rules will be brought to bear on every relationship of every reports.
Sharing of report preparations
Prior to performing the task of gathering and securing records, the ReadiNow reporting engine automatically performs a number of preparatory steps. This preparation work will be cached and shared among multiple users so long as those users are in the same roles. The roles must be the same, not just partially overlapping.
Report Object
A report is based on a particular object. Try to create reports using the most specific type of object for your purpose. For example, if the the purpose of the report is to show employee records, then ensure the report is created using the 'employee' object, and not the 'person' object. Even though the 'person' object is inherited by employee, using 'person' means all security rules that apply to the 'person' object, and every object that inherits from the person object, will be taken into consideration. This will impact performance. When designing applications, use objects and inheritance to classify different types of records, rather than choice fields (unless the classification is likely to be changed). This allows for more targeted access control rules to be created and reduces the number of access control rules that are applied when running a report.