PingOne Advanced Identity Cloud

Virtual properties

Properties can be derived from other properties within an object. This lets computed and composite values be created in the object. These derived properties are called virtual properties, and their value can be calculated in two ways:

  • Using a script called by the onRetrieve script hook. This script calculates the current value of the virtual property based on the related properties.

    For example, you may want to dynamically update a property that you use for a country code (for phone number purposes). When a user’s record is retrieved, the country code is dynamically calculated based off of the country property of the user’s record.

  • Using a query to identify the relationship fields to traverse to reach the managed objects whose state is included in the virtual property, and the fields in these managed objects to include in the value of the virtual property.

    These properties are called relationship-derived virtual properties (RDVPs).

    The default Advanced Identity Cloud schema defines several user properties as relationships. For information on how to define custom relationships, refer to Manage custom relationship properties.

Learn more about extending attributes of the user object in Customize user identities.

Derive virtual properties using onRetrieve scripts

The onRetrieve script hook lets you run a script when the object is retrieved. In the case of virtual properties, this script gets the data from related properties and uses it to calculate a value for the virtual property. Learn more in Extend functionality through scripts.

Only run onRetrieve scripts for top-level object fields.

Relationship-derived virtual properties

Virtual properties can be calculated by Advanced Identity Cloud based on relationships and relationship notifications. This means that, rather than calculating the current state when retrieved, the managed object that contains the virtual property is notified of changes in a related object, and the virtual property is recalculated when this notification is received. To configure virtual properties to use relationship notifications, there are two areas that need to be configured:

  • The related managed objects must be configured to use relationship notifications. This lets Advanced Identity Cloud know where to send notifications of changes in related objects.

  • To calculate the value of a virtual property, you must configure which relationships to check, and in which order, a notification of a change in a related object is received. You configure this using the queryConfig property.

The queryConfig property tells Advanced Identity Cloud the sequence of relationship fields it should traverse in order to calculate (or recalculate) a virtual property, and which fields it should return from that related object. This is done using the following fields:

  • referencedRelationshipFields is an array listing a sequence of relationship fields connecting the current object with the related objects you want to calculate the value of the virtual property from. The first field in the array is a relationship field belonging to the same managed object as the virtual property. The second field is a relationship in the managed object referenced by the first field, and so on.

    Example

    For example, the referencedRelationshipFields for effectiveAssignments is ["roles","assignments"]. The first field refers to the roles relationship field in managed/realm-name_user, which references the managed/realm-name_role object. It then refers to the assignments relationship in managed/realm-name_role, which references the managed/realm-name_assignment object. Changes to either related object (managed/realm-name_role or managed/realm-name_assignment) will cause the virtual property value to be recalculated, due to the notify, notifySelf, and notifyRelationships configurations on managed user, role, and assignment. These configurations ensure that any changes in the relationships between a user and their roles, or their roles, and their assignments, as well as any relevant changes to the roles or assignments themselves, such as the modification of temporal constraints on roles, or attributes on assignments, will be propagated to connected users, so their effectiveRoles and effectiveAssignments can be recalculated and potentially synced.

    • referencedObjectFields is an array of object fields that should be returned as part of the virtual property. If this property is not included, the returned properties will be a reference for the related object. To return the entire related object, use *.

    • flattenProperties is a boolean that specifies whether relationship-derived virtual properties should be returned as plain fields rather than as JSON objects with an _id and a _rev. This property is false by default.

      With flattenProperties set to false, and referencedObjectFields set to name, the response to a query on a user’s effectiveAssignments might look something like this:

      "effectiveAssignments": [
          {
              "name": "MyFirstAssignment",
              "_id": "02b166cc-d7ed-46b7-813f-5ed103145e76",
              "_rev": "2"
          },
          {
              "name": "MySecondAssignment",
              "_id": "7162ddd4-591a-413e-a30b-3a5864bee5ec",
              "_rev": "0"
          }
      ]

      With flattenProperties set to true, and referencedObjectFields set to name, the response to the same query looks like this:

      "effectiveAssignments": [
          "MyFirstAssignment",
          "MySecondAssignment"
      ]

      Setting flattenProperties to true also lets singleton relationship-derived virtual properties be initialized to null.

Using queryConfig, the virtual property is recalculated when it receives a notice that changes occurred in the related objects. This can be significantly more efficient than recalculating whenever an object is retrieved, while still ensuring the state of the virtual property is correct.

When you change which fields to return using referencedObjectFields, changes are not reflected until there is a change in the related object that would trigger the virtual property to be recalculated (as specified by the notify, notifySelf, and notifyRelationships configurations). The calculated state of the virtual property is still correct, but since a change is necessary for the state to be updated, the returned fields will still be based on the previous configuration.

Create an RDVP

RDVPs are useful because they allow you to query relationships. It’s not possible to query relationship properties directly. For example, you can create an RDVP to query which users have a manager whose email address contains a specific value.

  1. Create a new array property for the identity profile object:

    1. In the Advanced Identity Cloud admin console, go to Native Consoles > Identity Management > Configure > Managed Objects > User-type Managed Object and select an available frIndexedMultivaluedn property.

    2. Update the Readable title and Description fields.

    3. Click Save.

  2. On the Details tab, click Show advanced options.

  3. In the list, enable Virtual and then enable Return by Default.

  4. Click Save.

  5. Select the Query Configuration tab.

  6. In the Referenced Relationship Fields, enter the name of the relationship property or properties used to calculate the RDVP. In this example, the relationship property name is ["manager"].

    You must enter the relationship property name as a valid JSON array.
  7. In Referenced Object Fields, enter the name of the fields to return when the RDVP is calculated. In this example, the field names are _id and mail.

  8. Click Save.

    This process uses an indexed multivalued extension attribute, which lets you run a search on the RDVP. If you don’t need to run a search on the RDVP, you can instead use an unindexed multivalued extension attribute or a custom attribute with Type: Array. A custom attribute is saved as an array of objects so you’ll need to specify the relevant fields for some queries. Learn more in Customize user identities.

Verify the RDVP

After you’ve populated and saved the Referenced Relationship Fields for a user, the RDVP property shows values specified in Referenced Object Fields. For example:

Verify the RDVP

These are the RDVP values that you can query. Learn more in Query managed users by RDVP.

Query managed users by RDVP

As mentioned in Create an RDVP, RDVPs are helpful because they allow you to query relationship properties that you can’t query directly. For example, if you want to know which organizations have at least one owner or which users have a manager who has certain properties, such as an email that contains a specific value, then you can query an RDVP using REST.

You can query an RDVP using the _queryFilter parameter. For example:

curl \
--header "Authorization: Bearer <access-token>" \
--header "Accept-API-Version: resource=1.0" \
--request GET \
'http://<tenant-env-fqdn>/openidm/managed/alpha_user?_queryFilter=<filter>' (1)
1 <filter> is the query expression for the RDVP. Learn more in Construct queries.

Example RDVP queries

  • Which organizations have at least one owner?

    This query uses the existing ownerIDs RDVP:

    openidm/managed/organization?_queryFilter=ownerIDS+pr
  • Which users have a manager whose email address contains the value test?

    This query uses a custom RDVP where the RDVP is called frIndexedMultivalued1:

    _queryFilter=frIndexedMultivalued1+co+"test"

    If you’ve used a "custom_" attribute, you must also specify the field you’re querying. For example:

    _queryFilter=custom_testRDVP+[mail+co+"test"]