One of the most basic things everyone needs to do in SailPoint IDN (IdentityNow) is to write transforms to create an Identity Profile for business requirements.

SailPoint has a an excellent guide on what a transforms is and detailed list of transforms available for IDN and is pretty comprehensive. 

The simple ones are pretty easy to implement. But we always run into creating complex nested transforms to achieve our goals. It looked daunting to me at first but I started to get the hang of it. I would like to explain in very basic terms how to easily achieve this.

Let’s take a business case here to explain easily.


Build an emailPrefix attribute with firstName and lastName from Workday source which will be eventually used to generate an email address.


Now if we break down the requirement into logic, we need to do the following

  • Get firstName from Workday source
  • Get lastName from Workday source
  • Concat the two with a period (.) in the middle
  • Remove all spaces from the final value.

Since this is an emailPrefix to be used to generate an email attribute, it can’t contain spaces. There can be other requirements like special characters etc but let’s keep it simple here (that is just a matter of proper regex).


Now if you look at the transforms guide you will need the following transforms

To get the attributes from a source – accountAttribute

To concat the two attribute with a period – concat

And then finally we need to do a replace block to remove all spaces from the final result (note the \\s is the put \s as literal in JSON while passing it via REST API)

Now we need to join the three block. First we will begin with replacing the “firstName code block” and “lastName code block” with the accountAttribute block we had done above.

This will give us the concatenated value of “firstName.lastName”. But now we want to remove all spaces from it as it will be used for email address generation. 

If you look at the replace block above, we need to do two additional things to the code

  1. Give it an “id” key as we want to name this final transform for mapping
  2. Give it an “input” key as we want to explicitly define the inputs for this type (i.e. the concatenated string) and not use implicit value (i.e. from the IDN mapping). Do read about the difference in the transform guide.

So the new skeleton code for replace will become

The final step is now pretty easy. Replace the entire input value with the built concat value above.

And that is it!! You have built your first nested transform. It gives you the immense power to build a deep nested transform for complex logics to get glorious and simplified results in the end.


I am not an expert in this and still learning this every day even after playing with it for more than a year but here are my learnings

  • Write down the logic you want to achieve
  • Break it down to individual code blocks
  • Write down the nested logic which will achieve you the result in best way possible (in above example = get the attributes -> concat it -> replace spaces). We could have also done this by say getting each attribute, remove spaces from them individually and then doing a concat of the final result – but this is inefficient and longer code. So understanding the logic and making it smart and short is best way forward.
  • Start working from inside block to outside and encapsulating them to achieve result
  • ALWAYS use a good code editor with syntax highlighter – My fav is VS Code with various plugins (makes it an awesome Swiss army knife for coders).

Hope this helped you!!!

Stay tuned for some more tips and #IDN101


Mahesh · 11/18/2021 at 4:28 AM

Excellent article.

Would you be able to provide a similar example as how to use lookup transform along with concat.

Scenario: We have a requirement to generate username by adding prefix to email. Prefix is part of lookup transform and depends on the source.

Lookup Transform:
“attributes”: {
“table”: {
“sourceA”: “.abc”,
“sourceB”: “.def”,
“sourceC”: “.xyz”
“type”: “lookup”,
“name”: “username_suffix”

Account Create Profile for attribute “username” for “sourceA”:

“name”: “username”,
“transform”: {
“type”: “concat”,
“attributes”: {
“values”: [
“attributes”: {
“name”: “email”
“type”: “identityAttribute”
//Get prefix from lookup transform named “username_suffix”…What is the syntax for using above lookup transform. We need to retrieve value “.abc”

“attributes”: {},
“isRequired”: false,
“type”: “string”,
“isMultiValued”: false

    Piyush Khandelwal · 11/18/2021 at 6:39 AM

    Hi @Mahesh

    Best to get help at as there could be different approach to this. Not sure what your sourceA/B/C is here and since your create profile is on a particular source anyways, you could just do a static transform with velocity if else statements.

    You can also do this on profile level so it works for attribute sync (if needed)

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: