Using special operators in ABAC READ policy conditions
Using special operators in ABAC READ policy conditions
ABAC READ policy conditions that use special operators are susceptible to performance issues. This article talks about remediation options.
Before you begin
ABAC policy conditions typically compare attributes on a record (Work- / Data- / Rule-) with attributes of a requestor (a page on the clipboard) to check whether the current operator has access to perform a specific action (READ / UPDATE / DELETE). Policy conditions can be used to enforce instance-level and row-level security.
As of Pega 8.5, special comparison operators are shipped out-of-the-box to help with comparing lists of values. As per the help documentation: "The special comparison operators All Of and One Of can be used to compare two property values when each is a comma-separated list of one or more values. The comparison values that are referenced in policy condition filters must be existing Requestor properties or requestor-scoped data pages."
While these operators are very convenient for modelling the comparisons, this comes with a caveat when used on READ policy conditions that are used to enforce row-level security and can potentially work on a large set of data.
- When a report definition is executed, the corresponding SQL function pr_compare_value_lists_allof, pr_compare_value_lists_anyof is used in the Where clause of the query to filter out non-conforming rows.
- The SQL function pr_compare_.. will be invoked for each row, and because these are non-deterministic functions, function-based indexes cannot be used here.
If the list of rows to be checked is (m) and the list of values to be compared with is (n), then performance of the query is Big-O(m x n).
Use case examples
Every case has the value of the key required to open the case in the property ".Keys"; A list of keys that an operator has is maintained as a list of values in D_OperatorAccess.Keys as a "Value List" property.
Access to the case is granted if the key required to open the case is ANY_OF the list of keys the operator has. The system translates the ABAC policy condition to:
SELECT "PC0"."pyid" AS "pyID" , "PC0"."pylabel" AS "pyLabel" , "PC0"."pxcreatedatetime" AS "pxCreateDateTime", "PC0"."keys" AS "Keys" FROM pegadata.pc_O97LMY_CMR_Work "PC0"
WHERE ( ( "PC0"."pxobjclass" = ? AND
( CASE WHEN "PC0"."keys" IS NULL THEN 1 ELSE pegadata. pr_compare_value_lists_anyof("PC0"."keys",? ) END = ? )
) ) ORDER BY 1 ASC
Process/Steps to achieve objective
- For large sets (size of list of values is large OR table is voluminous), avoid using these functions if possible.
- Use forking logic in ABAC policy conditions using data-page based invocations of report definitions to filter out rows (through JOINs) in an indirect manner.
- Alternatively, update to Pega 8.6, which supports using associations in READ ABAC policy conditions.
Results
Following the above recommendations will help queries perform much better than when the above-mentioned special operators are used to compare lists of values.