IdentityNow Transforms - Username Generator

IdentityNow Transforms - Username Generator

Overview

The username generator transform allows you to specify logic to use when attempting to derive a unique value for an attribute in an account create profile, . Oftentimes this can be as simple as combining parts of a user's name and/or HR data (e.g., firstName.lastName), but sometimes generator logic such as a uniqueness counter might be needed to find a unique value in the target system (e.g., firstName.lastName1 if firstName.lastName is already taken).

Note: This transform can only be used for generation of unique value for the Account ID attribute marked for the source. For other attributes please use OOTB Create Unique LDAP Attribute Rule or create your own Attribute Generator Rule

Other Considerations

  • The transform allows for the use of "uniqueCounter" as a reserved variable for numerically trying the next iteration of the pattern. Once the generator is active on a pattern with "uniqueCounter," it will keep incrementing until it either has found a unique username candidate or it exhausts "cloudMaxUniqueChecks" value. This means that any patterns after one containing "uniqueCounter" will not be processed. The use of "uniqueCounter" should always be last in the pattern list.
  • Within the account attribute definition structure, there is a field for "cloudMaxUniqueChecks" that identifies how many times the uniqueness check logic should be invoked before the username generator should stop executing. The maximum allowed value for this field is 50.

 

Transform Structure

The username generator transform is intended to be used as a configuration within the account create profile for a source. As such, the structure of this transform is more extensive than a typical Seaspray implementation -- it must be assigned to a create profile attribute (designated by name) and provide certain uniqueness check attributes such as cloudMaxSize, cloudMaxUniqueChecks and cloudRequired.

The cloudMaxSize attribute denotes the maximum length of generated data that should be allowable as a result of the generator logic. Any characters over thecloudMaxSize are truncated. The cloudMaxUniqueChecks attribute determines the maximum number of iterations the generator should attempt before failing to generate a value. The cloudRequired attribute is an internal flag required for the IdentityNow platform, and can simply be left as true.

The username generator transform itself should be supplied in the create profile attribute entry's transform parameter.

Example

{
  "attributes": {
    "cloudMaxSize": "100",
    "cloudMaxUniqueChecks": "5",
    "cloudRequired": "true"
  },
  "isRequired": false,
  "multi": false,
  "name": "distinguishedName",
  "transform": {
    "type": "usernameGenerator",
    "attributes": {
      "sourceCheck": true,
      "patterns": [
        "CN=$fi.$ln,OU=Users,DC=YourDomain,DC=com",
        "CN=$fn.$ln,OU=Users,DC=YourDomain,DC=com",
        "CN=$fn.$mi.$ln,OU=Users,DC=YourDomain,DC=com",
        "CN=$fn.$mi.$ln${uniqueCounter},OU=Users,DC=YourDomain,DC=com"
      ],
      "fn": {
        "type": "identityAttribute",
        "attributes": {
          "name": "firstname"
        }
      },
      "ln": {
        "type": "identityAttribute",
        "attributes": {
          "name": "lastname"
        }
      },
      "fi": {
        "type": "substring",
        "attributes": {
          "input": {
            "type": "identityAttribute",
            "attributes": {
              "name": "firstname"
            }
          },
          "begin": 0,
          "end": 1
        }
      },
      "mi": {
        "type": "substring",
        "attributes": {
          "input": {
            "type": "identityAttribute",
            "attributes": {
              "name": "middlename"
            }
          },
          "begin": 0,
          "end": 1
        }
      }
    }
  },
  "type": ""
}

Attributes

  • Required Attributes

    • type - This must always be set to usernameGenerator

    • patterns - A JSON array of patterns for the generator to evaluate for uniqueness, in sequential order

      • Note that $uniqueCounter can be leveraged here to automatically increment a counter if the value generated is not available and you would like to try appending numeric values (i.e., 1, 2, 3, etc.) instead of progressing beyond the current pattern.
  • Optional Attributes

    • sourceCheck - A boolean value (true/false) to indicate whether the generator should check only the IdentityNow database's representation of accounts for uniqueness, or whether the generator should query the target system directly. If not provided, the attribute will default to false.

      • true indicates the generator should check the target system directly. This is honored only if the system supports the "getObject" functionality -- for systems that do not have the ability to query for single account objects, the setting here is ignored and defaulted to false.  Note also that only the attribute identified in the account schema as the accountID is checked.
      • false indicates the generator should check only the IdentityNow database of accounts.  Only the accountID is checked.

 

Examples

Example 1

{
  "attributes": {
    "cloudMaxSize": "100",
    "cloudMaxUniqueChecks": "25",
    "cloudRequired": "true"
  },
  "isRequired": false,
  "multi": false,
  "name": "userId",
  "transform": {
    "type": "usernameGenerator",
    "attributes": {
      "sourceCheck": true,
      "patterns": [
        "$fi$ln${uniqueCounter}"
      ],
      "ln": {
        "type": "identityAttribute",
        "attributes": {
          "name": "lastname"
        }
      },
      "fi": {
        "type": "substring",
        "attributes": {
          "input": {
            "type": "identityAttribute",
            "attributes": {
              "name": "firstname"
            }
          },
          "begin": 0,
          "end": 1
        }
      }
    }
  },
  "type": ""
}

This generator takes the user's first initial, appends the user's full last name, and then leverages a uniqueness counter to generate a unique value for userId. For example if the user's name were John Doe, the username generator will first try jdoe. If that is not unique, it will progress to jdoe1, then jdoe2, etc., until jdoe25.

Should a unique value not be found within those first 25 tries, then the generator will return an IllegalStateException.

Example 2

{
  "attributes": {
    "cloudMaxSize": "100",
    "cloudMaxUniqueChecks": "10",
    "cloudRequired": "true"
  },
  "isRequired": false,
  "multi": false,
  "name": "accountId",
  "transform": {
    "type": "usernameGenerator",
    "attributes": {
      "sourceCheck": true,
      "patterns": [
        "$fn.$ln${uniqueCounter}"
      ],
      "fn": {
        "type": "identityAttribute",
        "attributes": {
          "name": "firstname"
        }
      },
      "ln": {
        "type": "identityAttribute",
        "attributes": {
          "name": "lastname"
        }
      }
    }
  },
  "type": ""
}

This generator takes the user's first name, appends a period and then the user's full last name, and then adds a uniqueness counter to generate a unique value for accountId. For example if the user's name were Adam Smith, the username generator will first try adam.smith. If that is not unique, it will progress to adam.smith1, then adam.smith2, etc., until adam.smith10.

Should a unique value not be found within those first 10 tries, then the generator will return an IllegalStateException.

 

References

  • N/A
Comments

Hi,

Is there a way to create unique account attributes (not set as AccountID in account Schema) with a template array similar to this?
The 'Create Unique LDAP Attribute' generator uses just one pattern. Could an array be passed to it to check against multiple patterns similar to this transform?

Thanks in advance!

hey  @hari_patel , @efrain_sanchez  and @david_reeves .

 

How can i manage to use this transform for generate a unique samaccountName? I'm no able to do it een changing the AD Account ID to SamaccountName .

 

Can you guys hel pe ? 

 

Here is the transform and the error i'm getting 

{
    "attributes": {
        "cloudMaxSize""100",
        "cloudMaxUniqueChecks""5",
        "cloudRequired""true"
    },
    "isRequired"false,
    "multi"false,
    "name""sAMAccountName",
    "transform": {
        "sourceCheck"true,
        "attributes": {
            "fi": {
                "attributes": {
                    "begin"0,
                    "end"1,
                    "input": {
                        "attributes": {
                            "name""firstname"
                        },
                        "type""identityAttribute"
                    }
                },
                "type""substring"
            },
            "fn": {
                "attributes": {
                    "name""firstname"
                },
                "type""identityAttribute"
            },
            "li": {
                "attributes": {
                    "begin"0,
                    "end"1,
                    "input": {
                        "attributes": {
                            "name""lastname"
                        },
                        "type""identityAttribute"
                    }
                },
                "type""substring"
            },
            "ln": {
                "attributes": {
                    "name""lastname"
                },
                "type""identityAttribute"
            },
            "mi": {
                "attributes": {
                    "begin"0,
                    "end"1,
                    "input": {
                        "attributes": {
                            "name""nomeDoMeio"
                        },
                        "type""identityAttribute"
                    }
                },
                "type""substring"
            },
            "mn": {
                "attributes": {
                    "name""nomeDoMeio"
                },
                "type""identityAttribute"
            },
            "patterns": [
                "$fn",
                "$fn$li",
                "$fn$mi",
                "$fn$mi$li"
            ],
            
        },
        "type""usernameGenerator"
    },
    "type"""
}
 
ERROR

An unexpected error occurred: Exception evaluating rule: Cloud Account Attribute Transform sailpoint.tools.GeneralException: The application script threw an exception: java.lang.IllegalStateException: Error generating account username for identity:

USER , appName: APPP Exception error msg: Exhausted patterns to generate a unique username BSF info: Cloud Account Attribute Transform at line: 0 column: columnNo

Hi all,

Currently only the Account Id attribute is supported to use the Username Generator for.

For other attributes where you might use the Create Unique LDAP Attribute Rule (like sAMAccountName or mail), please either continue to use that rule or create your own generator. Please see here for more assistance on Generator Rules.

Hi @hari_patel , @ross_shwarts , @efrain_sanchez , @david_reeves ,

I just tried to upload the transformation like in Example 1 from my Postman to Sailpoint. 

Unfortunatelly I receive the follwoing Error message:

{
    "msg_template": "No such property: isRequired for class: com.cloudmasons.ApiTransformCreateCommand",
    "slpt_error_code": "SLPT-1005",
    "formatted_msg": "(SLPT-1005) No such property: isRequired for class: com.cloudmasons.ApiTransformCreateCommand",
    "exception_id": "179CC8C7DC7",
    "error_code": 1005,
    "exception_class": "groovy.lang.MissingPropertyException",
    "exception_detail": {
        "file": "ApiTransformController.groovy",
        "method": "create",
        "line_number": 72,
        "class": "com.cloudmasons.ApiTransformController"
    },
    "http_response_code": 500,
    "timestamp": "2021-06-02 11:47:09.895",
    "exception_message": "No such property: isRequired for class: com.cloudmasons.ApiTransformCreateCommand"
}
 
Can someone please help me?!
 
Thank you very much.
 
Best regards
Stephan

Hi there @Stephan_M  ,

I had the same issue when I was trying to create a username generator transform not too long ago. The issue I had though was that I was trying to create the transform in the wrong Postman call.

I was originally trying to do a POST to "{{url}}/api/transform/create". Instead, what's required here is to do a GET call to "{{url}}/api/accountProfile/list/{{source number}}". The source number here is from whichever connector you want to use the username generator transform for.

The result will come back, and you'll see in the JSON for each attribute a spot for a transform. This is where the username generator transform is applied. You place it in, configured as you want it, and then include everything else that came back from that previous GET call when you then make a POST to "{{url}}/api/accountProfile/bulkUpdate/{{same source number}}".

I would first backup whatever you had come back in that GET call before making this POST call. If successful, you should be able to go to the Create Profile tab for the connector and see that a custom transform is being applied to the attribute you placed the transform under.

Let me know if this works for you,

Dan

Hi @Stephan_M , based on the error message, it looks like you are trying to create a transform from Example 1. 

Please note the comments under Transform Structure. These examples are attribute configurations as part of an Account Profile (specifically, account create profile). These examples would be used for a source where the username is the Account Id rather than a source where the account Id is an internal system id (like Azure AD).

Also, you can use the beta APIs to handle updating the AccountProfiles (called Provisioning Policies in the APIs)

- List: https://developer.sailpoint.com/apis/beta/#operation/listProvisioningPolicies

- Get: https://developer.sailpoint.com/apis/beta/#operation/getProvisioningPolicy

- Update (via PUT): https://developer.sailpoint.com/apis/beta/#operation/replaceProvisioningPolicy

I tried the simplest version from gui and still got below error:

Error generating a unique value, the exception was: java.lang.Exception: Unable to contact connector to generate unique value and is not retry-able. Action:UniqueAccountIdValidator: Calling getObject for objectType 'account' using id 'AdaPrats' and options '{cloudConfigOverrides={aggregateTimeout=30, disablePooling=true, timeout=30}}' on source 'Prod AD (Prov) [source]'. Exception: sailpoint.connector.ConnectorException: [ InvalidConfigurationException ] [ Error details ] Required string attribute 'User' is not defined.It must have a valid value.

This is snippet for samaccountname (Account ID for AD source) from the ‘CREATE’ Provisioning policy 

 {

            "name": "sAMAccountName",

            "transform": {

                "attributes": {

                    "name": "Create Unique Account ID"

                },

                "type": "rule"

            },

            "attributes": {

                "template": "$(firstname)$(lastname)$(uniqueCounter)",

                "cloudMaxUniqueChecks": "5",

                "cloudMaxSize": "100",

                "cloudRequired": "true"

            },

            "isRequired": false,

            "type": "",

            "isMultiValued": false

        },

 

Please suggest if anyone has clue what can cause this type of error

@pradeepSB 

I am getting the same error while I am provisioning to AD. Have you resolved the issue?

 

Thanks.

 

What exactly does the cloudRequired attribute do? The article indicates:

The cloudRequired attribute is an internal flag required for the IdentityNow platform, and can simply be left as true.

If its only purpose is to be used internally, then why is it exposed? Would it be possible to update the article with a more clear explanation?

I also noticed there is another attribute, isRequried, which is set to false. Why would a Username not be required when creating a new account?

@pradeepSB Im facing the same issue, do you solved it??

 

Thank you in advance,

Regards

@pkumar22 

Im facing the same issue, do you solved it??

 

Thank you in advance,

Regards

@Beatriz 

 

we created a rule.

 

Thanks.

 

Version history
Revision #:
8 of 8
Last update:
Friday
Updated by: