Converting Identity Lifecycle State to Uppercase for AD Provisioning

Hi All,

We have a requirement to push the Identity Lifecycle State (LCS) to an Active Directory attribute in uppercase.

As you know, when the LCS is created in the Identity Profile, it is automatically converted to lowercase by design. From what I can see, the subsequent comparisons also appear to be case-sensitive.

For both the AD Account Create and Attribute Sync profiles, we need to map the LCS value and send it to AD in uppercase.

I can create a transform to convert the LCS to uppercase; however, doing so appears to affect the Identity Profile logic because of the case-sensitive comparison.

Another option would be to create a separate Identity Attribute specifically for the uppercase value, but that introduces duplicate data. Alternatively, this could be handled in a Before Provisioning (BP) rule, although that adds additional maintenance overhead.

Is there a simpler or recommended approach to achieve this common requirement?

Regards,

Hi @lalithajay

I wouldn’t recommend changing the Identity Profile value itself, since the Lifecycle State is intended to be used consistently throughout ISC and changing its case could affect lifecycle comparisons and other logic.

Instead, if the uppercase value is only needed by AD, I’d keep the LCS in its default format and apply the conversion only when provisioning to AD. That way, ISC continues to use the original lifecycle state while AD receives the value in the required format.

If you’re using a provisioning policy, have you tried applying a transform only to the mapped AD account attribute rather than to the Identity Profile attribute itself? That keeps the change local to the target system and avoids maintaining a duplicate identity attribute.

Hi @lalithajay

For ref, there is an Update Lifecycle State API (SailPoint ISC API (Beta)) however it doesn’t support updating the technicalName of the State, so it looks like you are stuck with the lower case technical name that is generated by ISC. And if, as you say, it is a case sensitive comparison, then your LCS transform will have to stay as-is.

The cleanest way is to use Attribute Sync and assign another Identity Attribute for “AD Lifecycle State”. Yes, it is “duplicate data”, but one does have to sacrifice that data design principle sometimes to enable Attribute Sync.

One thing to note is that the LCS transform is always processed last in an Identity Refresh, so from a timing perspective, you may need to duplicate your LCS logic, rather than rely simply on upper-casing the LCS value.

You could also investigate the use of an UPDATE provisioning policy (see SailPoint ISC API (Beta)).

Also, there is the possibility to get PowerShell to do the upper-casing with a Connector Executed Rule.

Hi @SuryaKiran

Thanks for your reply. That was initially my plan as well, to localise the logic. However, since this attribute change is required in both the CREATE and Attribute Sync provisioning policies, I need the value to be available at the Identity level (for example, as an Identity Attribute) to support both scenarios.

If this was only required for the CREATE operation, then a transformation at the mapping level would have been sufficient.

Another option would be to implement this logic within the AD Before Provisioning (BP) rule, but that is not my preferred approach from a maintenance perspective.

Hi @lalithajay ,

For keeping AD and ISC synchronized, I would recommend creating a new Identity attribute (for example, LCS_Upper) and associating it with a transform that simply converts the Lifecycle State value to uppercase.

You can then use this new Identity attribute in your AD provisioning policy and Attribute Sync mapping. This keeps the original Lifecycle State unchanged for ISC while providing the format required by AD.

As you already said the alternative would be to implement the conversion in an AD Before Provisioning Rule, where you intercept the provisioning plan and convert the value to uppercase before sending it to AD. However, this introduces custom logic.

The first approach is simpler.

I would consider pushing back on the AD requirement for the value to be in all-caps. There is no inherent technical need for this on the AD side, so it would be best for you to ask whether that is in fact a hard requirement and see if there are any alternate paths forward that don’t require it to be in all-caps. If there is some filtering downstream that is case-sensitive, can those filters simply be updated with an OR 'active' reflecting the actual styling of the LCS values?

Adding another Identity Attribute and transform is a possibility, but keep in mind that the more Identity Attributes you have, especially with transforms, the more overhead that is for SailPoint to calculate on every Identity Refresh, so it’s best to avoid adding more Identity Attributes all willy-nilly.

@lalithajay A simple and commonly used approach is to leave the Lifecycle State (LCS) attribute unchanged in the Identity Profile and create a separate transform only at the provisioning layer to convert the value to uppercase before sending it to Active Directory.

This avoids impacting the Identity Profile’s lifecycle state calculations and comparisons, which are based on the original lowercase LCS value.

Recommended Approach:

  • Keep the Identity Lifecycle State as delivered by SailPoint (lowercase).
  • Create a transform (for example, Static + Upper transform) that converts the LCS value to uppercase.
  • Use this transform directly in the AD Create Profile and Attribute Sync mapping for the target AD attribute.
  • Do not use the transformed value as the Identity Profile Lifecycle State attribute.

Why this approach?

  • No impact on LCS evaluation logic.
  • No duplicate identity attributes.
  • No custom Before Provisioning Rule maintenance.
  • Easier to support and troubleshoot.
  • Keeps SailPoint as the source of truth while meeting the AD formatting requirement.

A Before Provisioning Rule would also work, but I would consider it only if multiple sources require different formatting logic or if additional transformation rules are needed. For a simple uppercase requirement, a transform in the account/profile mapping is typically the cleanest solution.

Example:

JSON

{
“type”: “upper”,
“attributes”: {
“input”: {
“type”: “identityAttribute”,
“attributes”: {
“name”: “cloudLifecycleState”
}
}
}
}

Show more lines

Then map the AD attribute to this transform instead of directly mapping cloudLifecycleState.

This gives you:

  • Identity attribute: active
  • Value sent to AD: ACTIVE

without affecting lifecycle state processing in ISC.

Hi @vikaspawar0303

This sounds promising, and I was thinking along the same lines.

In the UI, I can certainly map this in the Create Account (Create Profile) by selecting Static and using the transform you mentioned. However, the part I’m struggling with is the Attribute Sync configuration. In the Attribute Sync profile, only Identity Attribute mappings seem to be available.

In a nutshell, I’m not clear on how this can be implemented through the UI for the AD Attribute Sync profile.

Could you shed some light on this aspect?

Thanks @j_place I was exploring more on SailPoint ISC API (Beta)

before update I tried getcall, below works for CREATE usage type and outputs values, but

fails for UPDATE usage type even though, I have few mappings already

“locale”: “en-US”,
“localeOrigin”: “DEFAULT”,
“text”: “Referenced template “UPDATE” was not found.”

after retrieving all the provisioning policies found out, I cannot see a one for UPDATE, Even though in the UI we got few attributes mapped under ‘Attribute Sync’ for this AD Source, I thought it contributes to a UPDATE provisioning policy

Attribute sync and having a provisioning policy of UPDATE type are separate pieces of functionality. You have to create the UPDATE policy using the API.

HI All,

Given there is already a existing BP rule for the source, and instead of having additional overhead of introducing another Identity Attribute, I injected the below code to BP rule and by looks it is doing the job required

Yes custom logic, but I felt below is a clean option considering there is already an existing BP rule

List accountRequests = plan.getAccountRequests();

		 ............
		 
		 ................
		 
		  if (accountRequests != null) {
			  
			  .....................
..................

         for (AccountRequest accReq : accountRequests) {			 
			
			String lcs = StringUtils.trimToNull(
                (String) identity.getAttribute("cloudLifecycleState")
            );

            if (lcs != null) {
                String upperLcs = lcs.toUpperCase(Locale.ROOT);
                AttributeRequest ad_attribute_01_req = accReq.getAttributeRequest("ad_attribute_01");

                if (ad_attribute_01_req != null) {
                    ad_attribute_01_req.setValue(upperLcs);
                 } else {
                    accReq.add(new AttributeRequest("ad_attribute_01", ProvisioningPlan.Operation.Set, upperLcs));
                 }
            }

............
............
............
			
			
			.......


Also agree below provisioning plan for UPDATE usagetype also worth exploring,

Create a new attribute in Identity profile and provide the value from aggregation. Later use that attribute for pushing to the target application.

Thanks Vikas, for now I did via modifying existing BP rule as explained above.

thanks for your help anyways