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.
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.
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?
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:
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.