Manual Lifecycle State updating automatically

I have observed behavior that I would not expect to occur and am wondering if it is a product bug.

Prerequisite Context: There is a non-negligible number of identities in my environment that have their lifecycle state set manually to a state that cannot be automatically assigned.

The behavior: When updating the transform that calculates lifecycle state and refreshing all identities, I noticed that the identities with manually set lifecycle state had their lifecycle state automatically recalculated. The reason why I think this could be a bug is that this behavior is incongruent with normal behavior experienced and documented, where lifecycle states do not get updated once they are manually set (unless the automatic logic also matches the manual set state). In my instance, the manual state cannot ever be reached via automatic logic so I would expect the identities moved to this manual state to never automatically exit the state.

Is this behavior expected or is this a product defect?

As far as I’m aware, a manually set LCS does not get changed, until the automatically calculated value will lead to a different value.

E.g. I set my LCS from ā€˜active’ to ā€˜manually offboarded’. Now my end date is reached, so I’m going into the ā€˜regular offboarded’ LCS, this will lead to this value being picked instead. See this note:

The manual setting is applicable as long as the underlying value on the source doesn’t change. When the value on the source changes, the Lifecycle State field gets reset to an automatic value.
For example, if Joe Smith’s lifecycle state is set to Active (Automatic), you can manually change the lifecycle state to Inactive (Manual). If the source value then changes from Active to OnLeave, the value in IdentityNow changes to OnLeave (Automatic).

From this doc:

It seems that changing the transform logic ā€˜counts’ as changing that input and therefore changing the LCS.

1 Like

I agree with your conclusion but the example does not apply since my manual state for identities can never be reached via automation logic. I still think this is not desired behavior and should be remediated from SailPoint. Otherwise, it makes recalculating lifecycle state almost impossible in my instance due to a large number of identities needing manual intervention after the new logic is applied. It also has the undesired consequence of triggering lifecycle based provisioning for users.

It is still the same field regardless, so I believe the logic does apply.

I do think however, that it would be a good idea to allow you to mark certain one or multiple Lifecycle States to never be changed once set manually, like a ā€œdon’t touch theseā€ setting.

One way to do this would be to have your transform that calculates the LCS to include the check if the current value of the LCS is indeed that manually set LCS. If it is, the transform will return that value. Then you will have to manually switch the LCS back to another value before it is considered for the regular LCS calculations again.

2 Likes

Hi all,

Sorry to revive this old thread, but this is the exact issue I’m working on right now.

I like the suggestion, and we have a very similar need for this sort of thing. The only part of grabbing the current lifecycle state attribute that I’m concerned about is the warning at the top of Identity Attribute | SailPoint Developer Community , which says the following:

ā€This transform is not intended for use within an another identity profile attribute’s calculation. Identity attribute calculations are multi-threaded processes, and there is no guarantee that a specific attribute has current data, or even exists, at the time of calculation within any given transform. Referencing identity attributes within another identity attribute’s calculation can lead to identity exceptions.ā€

I’m concerned about the possibility of exceptions when using this. Has anyone run into issues using this method of transform?

Hey Andrew,

I think the solution here (at least, what we ended up having to do) is setting the manual lifecycle state as ā€˜sticky’ in our cloudLifecycleState transform. We achieved this by having a static transform that wraps around all our CLS logic, where we have:

"type": "static",

    "attributes": {

        "lifecycleState": {

            "attributes": {

                "values": [

                    {

                        "attributes": {

                            "name": "cloudLifecycleState"

                        },

                        "type": "identityAttribute"

                    },

                    "<#default CLS state here#>"

                ]

            },

            "type": "firstValid"

        },
<# Insert your CLS logic here #>
"value": "#if($lifecycleState == 'manuallySetLifecycleState')manuallySetLifecycleState#{elseif}…#end"

    }

What this code snippet above does is say that upon recalculating lifecycle state (whether it be a transform update or whatever), then if the user is already in manuallySetLifecycleState, keep them there.

Thanks Dominick, I appreciate the psuedocode a lot. That’s pretty much how I was imagining it, so it’s great to know this has worked for someone else.