Working with Calculated Attributes
  • 05 Jan 2025
  • 11 Minutes to read
  • Dark
    Light
  • PDF

Working with Calculated Attributes

  • Dark
    Light
  • PDF

Article summary

Calculated Attributes Overview

Calculated Attributes enable dynamic Attribute transformation and enrichment within the PlainID Platform, allowing users to tailor Attribute values based on specific requirements. During PDP calculation, Attribute values can be set using calculated functions, values from other Attributes or sources, and optional fixed arguments. This capability also allows the manipulation of values mapped from other Attributes as input arguments for supported functions.

During runtime, the PlainID PDP evaluates Calculated Attributes, applies their transformations, and incorporates the results into the Identity. This enriched Identity is subsequently used for Policy evaluations, ensuring precise decision-making based on dynamic and context-aware data. This article includes information on Calculated Attributes in the PlainID PDP, error handling, and Calculated Functions with details and exceptions.

Ensure you follow the exact syntax detailed below to avoid validation or calculation errors. For more information about where to use Calculated Functions in The Platform UI, see our Managing Attribute Sources article.

Calculated Attributes in the PlainID PDP

Calculated Attributes enable dynamic calculation of Attribute values based on predefined functions and other Attributes values. Argument Attributes can initially derive their values from the PDP request, from mapping to an external source or from other calculated functions. The calculated values are then assigned to other Attributes, which are incorporated into the Policy evaluation process, supporting complex decision-making scenarios.
The Calculated Attributes capability can be used with Identity Attributes by defining a new Identity Source using the Calculated Source Type.

Runtime Evaluation Process

By leveraging Calculated Attributes, the PlainID PDP (Runtime Service) utilizes Calculated Attributes to modify Attribute values, preparing them for use in Policy evaluations. This enhances flexibility in Policy modeling and authorization request processing. The PDP supports various predefined calculated functions, including CONCAT, SUBSTRING, and REGEXEXTRACT, enabling advanced data manipulations.

  • Identity Flow:
    • After extracting data from Identity Sources, the PlainID PDP evaluates any defined Calculated Attributes and constructs the Identity.
    • The extracted data, retrieved from sources, is assigned to Attributes. These Attributes can be used as arguments when applying specified functions based on the order and dependencies of calculated functions.
    • Once calculated, mapped Attributes are assigned the function result values and integrated into the complete Identity along with all other Attributes derived from other sources.
    • The combined Identity is then processed as part of the Policy evaluation.

Important Notes:

  • Some functions can handle Multi Value source argument Attributes, resulting in either a single-value or multi-valued result, while others may cause a calculation error. See the Multi Value Examples section for more information.
  • Empty values in argument Attributes may lead to either an empty calculation result or a calculation error.
  • If supported by Calculated Functions, each Identity permutation receives specific calculated Attribute values when the PDP uses the combinedMultiValue request flag to process multiple Identity permutations.

Error Handling

Verify the syntax and update it as necessary, or contact PlainID Customer Support for assistance. If an error occurs while validating or processing Calculated Attributes, the system handles it according to the failOnCalculatedAttributesErrors configuration in the Permit Deny, User Access Token, Policy Resolution, and Policy List endpoints:

  • When set to true: The process stops, and an error message appears.

  • When set to false: The error is logged as a warning with the message PlainID-error-Calc.

Skipped Calculations
Calculated Attributes are skipped in the following cases:

  • The Attribute is not referenced in any Policy logic.
  • The includeAttributes flags are not enabled for the request.

In the case of skipped calculations, the Attribute value defaults to PlainID-skipped-Calc.

Calculated Functions

Calculated functions allow you to dynamically derive values based on specified rules and inputs, enhancing the flexibility and efficiency of your configurations. These functions use a straightforward syntax and support various operations, such as string manipulation, concatenation, and pattern matching.

To ensure correct implementation, follow these key syntax guidelines:

  • Use capitalized function names.
  • Enclose function arguments in parentheses.
  • Include at least one Attribute argument, specified using its Attribute ID within double curly braces (e.g., {{attribute}}).

The table below provides a comprehensive overview of supported calculated functions, including their syntax, practical examples, and explanations.

Calculated Functions Table

Refer to the table below for the supported Functions, their syntax and how to use them:

Function (with Syntax)ExplanationExampleSupports Multi Value
Substring

SUBSTRING({{attribute}}, beginIndex, endIndex)
Extracts part of an Attribute value string as the Calculated Attribute value. The substring begins at the specified beginIndex and extends to the character at index endIndex - 1

Arguments:
- {{attribute}} : Attribute ID (single/multi value)

- beginIndex: Substring extraction starting point integer value (0 based)

-endIndex: The location (integer value) of the character after the last one to extract. The function extracts from beginIndex to endIndex - 1.
SUBSTRING({{attrA}}, 4, 3)

attrA = abc-def

Result = def
Yes

E.g.
SUBSTRING({{attrA}},0,2)
attrA = [abc, def, xyz]
Result= [ab, de, xy]
Concat

CONCAT(list of params)
Sets the value of Calculated Attribute by concatenating the values of other Attributes with or without a delimiter of fixed text.

Arguments:
list of parameters - Including one or more {{attribute}} params and additional optional string params like "-", " "etc.

Note: list of params must include at least one Attribute in the form of {{attribute}}
CONCAT({{attrA}}, "-", {{attrB}})
attrA = abc
attrB = def

Result = abc-def
No
Lower

LOWER({{attribute}})
Sets a string value to lower-case

Arguments:
{{attribute}}: Attribute ID (single/multi value)
LOWER({{attrA}})
attrA = ABCD

Result = abcd
Yes

E.g.
LOWER({{attrA}})
attrA=[ABC, DEF, XYZ]

Result: [abc,def,xyz]
Upper

UPPER({{attribute}})
Sets a string value to upper-case

Arguments:
{{attribute}}: Attribute ID (single/multi value)
UPPER({{attrA}})
attrA = abcd
Result = ABCD
Yes

E.g.
UPPER(attrA)
attrA=[abc, def, xyz]

Result: [ABC, DEF, XYZ]
Join

JOIN(delimiter, list of params)

Concatenating a list of params with a fixed delimiter between each item

Arguments:
- delimiter: String value of the join delimiter wrapped in double quotes.

-list of params: List of Attributes and/or string values
JOIN("-", {{attrA}}, {{attrB}}, {{attrC}})
attrA = abc
attrB = def
attrC = ghi

Result= abc-def-ghi
No
Split

SPLIT({{attribute}}, delimiter, [nElement])
Supports splitting a string using a delimiter and taking the nth element

Arguments:
- {{attribute}}: Attribute ID (single/multi value)
-- single value Attribute if nElement is not present.
-- multi value Attribute if nElement is present

- delimiter - String value of the split delimiter wrapped in double quotes

- nElement - optional integer value of the item number (zero based) to extract after the split.

Special characters in the function arguments require escaping. See the section on Escaping Special Characters for more information
SPLIT({{attrA}}, "-", 1)
attrA = abc-efg-ghi

Result= efg


SPLIT({{attrA}}, "-")
attrA = abc-efg-ghi

Result= [abc, efg, ghi]


SPLIT({{attrA}}, "-", 2)
attrA = [a-b-c, e-f-g, g-h-i]

Result= [c, g, i]
Yes. However if more than one argument is returned, it is not supported.

See the Split Multi Value Examples table below for more information.
Replace

REPLACE({{attribute}}, target, replacement, [occurrenceIndex])
Replaces a specified string with an Attribute value, whether all occurrences or the nth occurrence.

Arguments:
- {attribute}}: Attribute ID (single/multi value)

- target: String value to search as the target for replacement

- replacement: String value to use as replacement instead of the target

- occurrenceIndex: optional integer value of the target/searched string occurrence (zero-based) to be replaced. If not present all occurrences are replaced.

Special characters in the function arguments require escaping. See the section on Escaping Special Characters for more information
REPLACE({{attrA}}, "abc", "xyz", 1)
attrA = abc-efg-abc

Result= abc-efg-xyz



REPLACE({{attrA}}, "abc", "xyz")
attrA = abc-efg-abc

Result= xyz-efg-xyz
Yes

E.g.
REPLACE({{attrA}},'z','k')
attrA= [abc,dzf,xyz]
Result=[abc, dkf, xyk]
Regex Extract

REGEXEXTRACT({{attribute}}, pattern, [nElement])
Supports Regex functions to allow value extraction through patterns**<br

Arguments:
- {{attribute}}: Attribute ID (single/multi value)

- pattern - a valid Regex pattern with or without grouping using ()>
- nElement - optional integer value of the index number (zero based) to extract incase of multi match. If omitted, all matches are extracted and the result is a multi value.

Special characters in the function arguments require escaping. See the section on Escaping Special Characters for more information
REGEXEXTRACT({{attrA}}, "account-(\d*)", 0)
attrA = account-123

Result = 123
Yes
If several matches are found, they are not supported. See the Regex Multi Value Examples table below for more information.
Escaping Commas

Note that commas require escaping in all functions.

Important

With nElements, beginIndex, and occurrenceIndex, values are index/zero-based indices.

Escaping Special Characters

When using functions like SPLIT, REPLACE, or REGEXEXTRACT in Calculated Attributes, certain special characters in the function arguments require escaping. Escaping is necessary to ensure these characters are treated as literal values rather than function modifiers. Escaping is done by prefixing the special character with a backslash (\\).

The following special characters must be escaped when used as arguments in functions: .$|[{^?*+

Using Parentheses and Backslashes

Currently, parentheses and backslashes cannot be used in patterns.

Examples:

  • Splitting by a period (.):
    To split the value abc.def into [abc, def], use:

    SPLIT({{attr}}, "\\.", 0)
    
  • Splitting by a pipe (|):
    To split the value abc|def and get the first part (abc), use:

    SPLIT({{attr}}, "\\|", 0)
    
  • Splitting by a string like (a):
    To split the value 123(a)456 by (a) and get the second part (456), use:

    SPLIT({{attr}}, "\\(a\\)", 1)
    
  • Splitting by a pipe with spaces (|):
    To split the value abc | def and get the first part (abc), use:

    SPLIT({{attr}}, "\\| ", 0)
    
  • Splitting by two pipes (||):
    To split the value abc||def and get the first part (abc), use:

    SPLIT({{attr}}, "\\|\\|", 0)
    
  • Characters that do not require escaping:
    Characters that are not part of the special character list, such as the hyphen (-), do not require escaping. For example, splitting by a hyphen:

    SPLIT({{attr}}, "-", 1)
    

By correctly escaping these special characters, you ensure that functions like SPLIT, REPLACE, and REGEXEXTRACT work as expected without errors.

Multi Value Examples

Split Multi Value Examples

Index DefinedArgumentResultExample
YesSingle ValueSingle ValueSPLIT(attrA,'-',2), attrA:'a-b-c' → Result: ‘c’
YesMulti ValueMulti ValueSPLIT(attrA,'-',2), attrA:['a-b-c', 'x-y-z'] → Result: [‘c’, 'z']
NoSingle ValueMulti ValueSPLIT(attrA,'-'), attrA:'a-b-c' → Result: [‘a’, ‘b', 'c’]
NoMulti ValueERRSPLIT(attrA,'-'), attrA:['a-b-c', 'x-y-z'] → Result: PlainID-Err-Calc

Regex Multi Value Examples

Index DefinedArgumentResultExample
YesSingle ValueSingle ValueREGEXEXTRACT(attrA,'[a-z]{1}',2), attrA:'a-b-c' → Result: ‘c’
YesMulti ValueMulti ValueREGEXEXTRACT(attrA,'[a-z]{1}',2), attrA:['a-b-c', 'x-y-z'] → Result: [‘c’, 'z']
NoSingle ValueMulti ValueREGEXEXTRACT(attrA,'[a-z]{1}'), attrA:'a-b-c' → Result: [‘a’, ‘b', 'c’]
NoMulti ValueMulti ValueREGEXEXTRACT(attrA,'-(\d{3})'), attrA:['123-456', ‘123-789’] → Result: [456, 789]
NoMulti ValueERRREGEXEXTRACT(attrA,'[a-z]{1}'), attrA:['a-b-c', 'x-y-z'] → Result: PlainID-Err-Calc

Use-Case Example

This use case demonstrates using calculated Attributes to match orders from an API request with customer data.

Scenario Overview
Your Application uses PlainID to Authorize data using API access capability.The Application sends an API request with a list of orders with multiple fields:

{
  "orders": [
    { "orderID": "98765", "orderType": "A", "orderAmount": "500" },
    { "orderID": "87654", "orderType": "B", "orderAmount": "300" }
  ]
}

User orders are fetched and matched with PIP using REST API request, returning list of full order detail field:

{
  "orders": ["98765-A-500", "87654-B-300"]
}

The Policy enforces authorization to orders based on full order details matching related to users.

  • Extracting Order Information into Identity Attributes

Three calculated Attributes are created at the Identity Template level, using SUBSTRING or SPLIT functions:

  • orderID: SUBSTRING({{orders}}, 0, 5) or SPLIT({{orders}}, "-", 0)
  • orderType: SUBSTRING({{orders}}, 6, 7) or SPLIT({{orders}}, "-", 1)
  • orderAmount: SUBSTRING({{orders}}, 8, 11) or SPLIT({{orders}}, "-", 2)

The Policy matches Attributes using multi-value matching and entity. rules. After calculating the additional Attributes, the Identity has the data structured similarly to the Asset and the matching can be done.


Known Limitations

Nested Functions
The ability to use one function inside another, such as SUBSTRING(UPPER('abcd'), 0, 2), is currently not available. Attempting to use nested functions results in a validation failure.

Solution
To achieve similar functionality, you can use additional Attributes as placeholders to store values, which can then be used in subsequent calculations. For example:

  1. Define an Attribute to store the result of the first function:

    attr1 = UPPER({{attr0}}) with attr0='abcd'  
    Result: 'ABCD'  
    
  2. Use the result as input for the next function:

    attr2 = SUBSTRING({{attr1}}, 0, 2)  
    Result: 'AB'  
    

By leveraging this approach, you can effectively chain calculations instead of nesting them.


Circular Functions
A circular dependency occurs when two or more Attributes depend on each other in a way that creates an endless loop. Calculated Attributes do not support circular dependencies in calculated functions. If a circular dependency is detected during the save process, a validation alert is displayed, and the function cannot be saved or deployed.

If a circular dependency is not caught during saving, Runtime validation protects the calculation process by throwing an indicative error and logging details about the circular reference. The log provides guidance for resolving the issue.

Example:

  1. attr1 depends on attr2:

    attr1 = CONCAT({{attr2}}, {{attr3}})  
    
  2. attr2 depends on attr1:

    attr2 = CONCAT({{attr1}}, {{attr3}})   
    

In this case, attr1 depends on attr2, and attr2 depends on attr1, creating a circular reference that cannot be resolved. Attempting to save or process these Attributes triggers a validation error.


Correlation Attributes and Context Filters
Calculated Attributes cannot be used as correlation Attributes or context filters in External templates due to dependencies and order constraints. These limitations arise from the need to ensure proper evaluation during the calculation process.


Complex Regex
The Regex Calculation theoretically supports any valid Regex pattern. However, it is designed to suit relatively simple data manipulations on Attribute values.
Note that Complex Regex patterns might not be supported and could impact the calculation, leading to unexpected results or performance issues.


User List
User List does not yet support Calculated Attributes.



Was this article helpful?