Referencing $oldValue of one identity attribute in a transform mapped to another identity attribute

Consider two identity attributes:

  1. identityAttributeA (has a transform mapped called transformA which returns $oldValue)
  2. identityAttributeB (has a transform mapped called transformB which wants to use the $oldValue and the current value of identityAttributeA to make some decisions.)

I want to use the old value of identityAttributeA in the transform transformB mapped for identity attribute identityAttributeB.
I explored the use of a reference transform to populate the value in a variable, but that did not work, i.e. reference transform to call ‘transformA’ from transformB.

Is this possible? And is there a different or a better way to do this?

1 Like

Would using an IdentityAttribute transform inside transformB not work?

"myOldValue" : {
   "type": "identityAttribute",
    "attributes": {
        "name": "identityAttributeA"
    }    
}

@iamnithesh That’ll only get the new value and not the old value of identityAttributeA. For old value, we can get it through a transform using the OOTB variable called $oldValue, so that’s what I was trying to get while calculating a value for identityAttributeB.

P.S: When I say “old value”, I mean if the identityAttribute A changed during the last refresh, which is when it makes sense to have an old value and a new value. If there are no changes, the oldValue will be the same as the current value.

So if I understand correctly you have two attributes A & B. In order to calculate B you need to reference both the old and new values of A?

If so, then you are most likely going to have to create an attribute C to store the old value while A stores the new value. I don’t believe there is a way to call forth both the old and new value of A inside a transformation for B. I would not expect the namespace to have that information as you are effectively requesting IDN to calculate both A & B within the same namespace. I suspect the product was designed to have each attribute calculation run individually within its own namespace.

At best you could potentially leverage a Idenitty Attribute rule which may provide a snapshot of the identity prior to the refresh.

You could also leverage the sequential order in which IDN calculates the attributes. For example, using a IdentityAttribute type transform to reference the current value of A which could potentially get you the old value if IDN calculates B before A. Then use a reference to the A transform to get the new value of A. However, I would advise against this as there is no guarantee to the order in which attributes are calculated. Thus, storing the old value in a new attribute is probably the safest and most sound approach with the smallest investment of time.

1 Like

@bostelmann Thanks for the inputs!

So what you’re suggesting I try is one of two main approaches, the first one being storing the old value of ‘A’ in a new attribute ‘C’, and then use both A and C for calculating B. I just had one quick follow-up question on this: This is very similar to my original problem of being able to store the old value of one attribute in another. Do you know of a good way to achieve this?

In the second approach that you suggested, you’re thinking of an identity snapshot before the refresh, correct? That’s a good option to explore too if it is available to use within the Identity Attribute Rule, but I do not see it coming as an input. We do however get the old value as input, but it’s only for the attribute the rule is mapped to. Is there a way we could achieve the passing of the old value of another attribute as an input to the rule, or invoke the old value of that other attribute, from within the cloud rule?

A Real-life Example of this problem (Expand for details)

Let me try to provide a more realistic example of the problem I’m trying to solve:

Consider there are two attributes:

  1. cloudLifecycleState (the usual lifecycle state attribute)
  2. paidLeaveToTerminatedFlag (a flag that is true if state change was from Paid Leave to Terminated, false otherwise)

I want to write a transform for the attribute paidLeaveToTerminatedFlag, where I need the current value of cloudLifecycleState and also the previous value of cloudLifecycleState. Only when I detect that the previous state was Paid leave, and the current state is Terminated, I want to set the flag to true, and set it to false otherwise.

Now this flag will be my trigger for, say a specific section of the downstream provisioning logic in a JDBC provisioning rule or say an AD powershell script. Can we do this?

Ah, thank you for the details.

As a notice, I do not have access to a tenant so I can’t test anything out. You will have to bear with me if I lead you astray.

In response to the Identity Attribute Rule, you have access to the complete identity object. See the documentation for more details.

What is uncertain is the state of the identity object that is passed into the rule. Is the object updated in real time as it is undergoing the refresh or is it stale data based on the identity at the start of the refresh.

If it is stale data base on the identity at the start of the refresh, then this solution would work fine for you as the old value would be stored in the identity object. To add further, you can actually access the identity object from within a transform as it is accessible by the Apache Velocity engine; documentation for details. So, the rule may be unnecessary complexity as you could get by with a transform.

If the object is updated in real time as the system calculates the new values for each attribute, then you have a race condition as attribute A may have already been refresh and you lost its old value.

I cannot speak to how SailPoint developed out the functionality and it may be worthwhile to get in contact with them. Alternatively, you could do lots of black box testing until you are confident in your understanding.

If we encounter the race condition, you could use the quick and dirty solution below:

Create a new attribute, C, to store both the old and new values of A. e.g. C = Leave,Terminated. The below transform should work to ensure C is calculated properly.

{
    "name": "Get Attribute C",
    "type": "static",
    "attributes": {
        "currentAValue": { //This transform will return the value of A prior to the refresh. e.g. Terminated.
            "type": "split",
            "attributes": {
                "delimiter": ",",
                "index": "1",
                "input": {
                    "type": "static",
                    "attributes": {
                        "value": "$oldValue"
                    }
                }
            }
        },
        "newAValue": { //This transform will return the expected value of A after the refresh.
            "type": "reference",
            "attributes": {
                "id": "Get Attribute A"
            }
        },
        "value": "#if($newAValue != $currentAValue)$currentAValue,$newAValue#{else}$oldValue#end"
    }
}

Then when you want the retrieve the old value of A you would use the below transform.

{
    "name": "Get Attribute A (Old)",
    "type": "split",
    "attributes": {
        "delimiter": ",",
        "index": "0",
        "input": {
            "type": "reference",
            "attributes": {
                "id": "Get Attribute C"
            }
        }
    }
}

Alternatively, you may be able to get by using a workflow. The Identity Attribute Change trigger will be able to capture this scenario perfectly.

3 Likes

@bostelmann Thanks a lot! Without trying it in an environment if you got this far, that’s commendable! Kudos!

1 Like

hah, thank you! Let me know how it goes. I suspect you will encounter some issues with the transform and may need to set a default value for it to not error out.

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.