Substring Transform within Workflow

Hello,

I am currently working on a workflow that will detect identities whose OU in Active Directory is not the same as the manager they report to, and creates a ticket for IAM to remediate. I am using the attribute AD DistinguishedName and comparing them to the managers AD Distinguished Name. The attribute is a string, but is comprised of a CN and 2-3 OU’s following the CN, please see attached image below.

The CN will always be the identity’s display name, so comparing them in the workflow will always result in the attribute not matching. My plan was to use the Define Variable step in the workflow, and use a Substring Transform within that define variable step that just removes every character before the first OU. The starting point for the substring transform needs to be dynamic in order to account for CN’s being different lengths every time due to different display names, so I used $.getIdentity.attributes.displayName.length() to be the starting point for the substring. My issue is that I need more than just the displayName length, I need an additional 4 characters on top of displayName length to account for “CN=” and the comma after the CN value. Does anyone know of a way to add 4 to the display name length or another workaround for this problem?

If I can’t utilize the substring transform, my next option was the replace transform and try to use regex to remove everything before the first comma, but I feel like this can be done with the substring transform. Any help is appreciated, thank you!

Hi @mosareini ,
Greetings of the Day!

Kindly note that we can use split transform in place of substring please check the below example

Input: "CN=ABC,OU=Test,DC=com"
Output: "OU=Test,DC=com"

Transform Request Body:

{  "attributes": {  
  "delimiter": ",",
    "index": 1
  },  
"type": "split",
  "name": "Split Transform"
}

Thank You

Here’s another approach to your requirement - using two define variables operators and compare strings, but you need to have dn populated on the identity cube

  1. On Define variable1 operator - create two variables named as userDNIndex and managerDNIndex. Get the userDN and mangerDN values from Get Identity action (example CN=sameer,OU=privileged,OU=users,DC=test,DC=com) and CN=tawargeri,OU=privileged,OU=users,DC=test,DC=com) and apply Get Index operator on them with pattern “,”. This gives an integer result on userDN(my example 9) and managerDN(my example 12).

  2. On Define variable2 operator - create two more variables named as userDNBasePath and managerDNBasePath and get the userDN and managerDN values again just like previous step. But this time add substring operator to them with substring starts with userDNIndex (9;obtained from previous Define Variable1 operator) on userDNBasePath variable and remove length of substring from Advanced editor tab resulting in ,OU=privileged,OU=users,DC=test,DC=com. Similarly on managerDNBasePath apply substring starts with managerDNIndex and remove length from Advanced editor resulting in ,OU=privileged,OU=users,DC=test,DC=com.

  3. Perform Compare strings, between userDNBasePath equals/matches managerDNBasePath. If not true create ticket

1 Like

There is no split transform in workflow :upside_down_face:

Hi @Yathish thank you for you information I am aware on that.

@mosareini check my suggestion below

Step1:
Add one Attribute in Identity Profile and add the below transform

Add you SourceName

{

	"attributes": {
		"user": {
			"attributes": {
				"dn": {
					"attributes": {
						"values": [
							{
								"attributes": {
									"sourceName": "Active Directory",
									"attributeName": "distinguishedName"
								},
								"type": "accountAttribute"
							}
						]
					},
					"type": "firstValid"
				},
				"value": "#set($cnToRemove = $splittf)#if($dn.contains($cnToRemove))#set($dn = $dn.replace($cnToRemove, ''))#set($dn = $dn.replaceFirst(',', ''))#end$dn",
				"splittf": {
					"attributes": {
						"input": {
							"attributes": {
								"values": [
									{
										"attributes": {
											"sourceName": "Active Directory",
											"attributeName": "distinguishedName"
										},
										"type": "accountAttribute"
									}
								]
							},
							"type": "firstValid"
						},
						"delimiter": ",",
						"index": 0
					},
					"type": "split"
				}
			},
			"type": "static"
		},
		"Manager": {
			"attributes": {
				"dn": {
					"attributes": {
						"values": [
							{
								"attributes": {
									"sourceName": "Active Directory",
									"attributeName": "manager"
								},
								"type": "accountAttribute"
							}
						]
					},
					"type": "firstValid"
				},
				"value": "#set($cnToRemove = $splittf)#if($dn.contains($cnToRemove))#set($dn = $dn.replace($cnToRemove, ''))#set($dn = $dn.replaceFirst(',', ''))#end$dn",
				"splittf": {
					"attributes": {
						"input": {
							"attributes": {
								"values": [
									{
										"attributes": {
											"sourceName": "Active Directory",
											"attributeName": "manager"
										},
										"type": "accountAttribute"
									}
								]
							},
							"type": "firstValid"
						},
						"delimiter": ",",
						"index": 0
					},
					"type": "split"
				}
			},
			"type": "static"
		},
		"value": "#if($Manager==$user)True#{else}False#end"
	},
	"type": "static",
	"name": "Static Transform Compare DN Manager"
}

After applying the above transform for the newly created attribute then the output contains True or False ,so use this attribute in workflow using compare strings operator, if the identity attribute(newly attribute)
value equals to false the next step wii be create tickets .Let me know for any queries.

Thank You
Mahesh

This solution is not feasible because a trigger is necessary to initiate any workflow. While the identity attribute will be set to true or false, it cannot be used to trigger the workflow. Additionally, as a best practice, we should avoid creating random identity attributes on an ad-hoc basis. What @sameertawargeri suggested is the best/only way to use this in the workflow scenario.

1 Like

@sameertawargeri This worked!!! Genius solution Sameer, thank you so much for your help!

This is an elegant solution, but why not take it a step further and incorporate it into the UPDATE function and have Sailpoint move the user to the correct OU instead of raising a ticket:
Create 2 identity attributes
ActiveParentOU - where they should be (use a transform to concatenate their CN with their Manager’s DN)
ActualParentOU - where they are
then:

          {
            "name": "Update Account",
            "description": null,
            "usageType": "UPDATE",
            "fields": [
              {
                "name": "AC_NewParent",
                "transform": {
                  "type": "static",
                  "attributes": {
                    "value": "#if($activeParentOU != $actualParentOU)$activeParentOU#{else}#end",
                    "activeParentOU": {
                      "type": "reference",
                      "attributes": {
                        "id": "Active Parent OU"
                      }
                    },
                    "actualParentOU": {
                      "type": "reference",
                      "attributes": {
                        "id": "Actual Parent OU"
                      },
                      "ignoreErrors": false
                    }
                  }
                },
                "attributes": {},
                "isRequired": false,
                "type": "string",
                "isMultiValued": false
              }
}
1 Like

@phil_awlings I wasn’t asked to automate the OU placement just yet, it’s a possibility in the future, but currently my ask is to get a ticket generated in ServiceNow so the IAM team can look into the anomalies and remediate them. Not every identity will need to be placed in their managers OU, we do have some one off scenarios where an actual analyst will need to investigate and determine the proper OU.

1 Like

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