Validate unique UPN with a rule

We have three AD connectors to the same domain. Handling multiple account creations within AD, such as privileged accounts, etc.

On account creations we need to make sure the UPN is unique.

In looking at the documentation we need to submit an Array of sources for it to query.

If we use the below, would this handle it or would we have to hard code the sources?
List SOURCE_IDS = new ArrayList( Arrays.asList(new String{application.getId()}));

I’m guessing this above command is only returning the Id for the connector the rule is running against. I’m also assuming it would be constrained to the scope for that connector. Such as if the connector was configured for several OU structures under the domain rather than the domain itself. Similar to an LDAP search where the base is used. What is the base with these calls?

Would we have to query all three sources independently? Or could our query for the given connector be able to determine that all user objects in AD don’t have a given UPN?

I was just having this conversation with @tyler_mairose - and we think it might be possible to pass in these IDs via a Generic Rule and call it from a transform in the create profile rather than using an Attribute Generator rule and calling that directly. However, you would also then need to use a transform to pass in identity information to use in the UPN, such as first and last name, since you wouldn’t have access to the Identity object.

Generic Rule | SailPoint Developer Community

I haven’t had a chance to build and test this yet, but I can report back later. But like you said, the method you shared with getID will only get the ID of the application you’re using, and since you’re searching multiple applications (assuming with Search Attributes) you’ll want all of the IDs.

1 Like

Looking at using identity.getStringAttribute to populate the data values, such as first and last name.

To confirm, I’m assuming that we are constrained to the base from the AD connector configuration, that when you set the base in the connector configuration, it will be used for all calls to the source, does that sound right?

If there is a different way, where we wouldn’t have to set static values in the rule where a sandbox would be a different rule than production, that would be ideal. But I’m assuming we can’t submit the LDAP base to search in a rule. Would that be a possible consideration for an enhancement, where a different base could be used if specified?

Hi @ts_fpatterson,

We have had a similar requirement and had to hardcode the source ID values :

List SOURCE_IDS = new ArrayList(Arrays.asList(new String[]{"207fb35bd61d538632075e76a53393","b969543b09a14771c3640bc9888ee6"}));

And for your other question, isUniqueLDAPValue method seems to directly look into the LDAP type endpoints (whereas the other methods look at the aggregated values). I haven’t tested it out though.

1 Like

That assumes you have the Identity object in the rule, in an Attribute Generator you do. If you switch to a Generic Rule type you will no longer.

If you want to search across multiple sources in one line of code you want to use search attributes and call idn.attrSearchCountAccounts(SOURCE_IDS, PROMOTED_ATTR_NAME, SEARCH_OP, SEARCH_VALUES)). If you setup the search attributes, this will search across all the IDs you provided. So for example, you could check the user principal name against 3 AD instances, an Azure, and Workday all in one fell swoop.

Using ISCRuleUtil as a Wrapper for Common Rule Operations | SailPoint Developer Community

1 Like

If you’re using a rule type that has access to the application variable (e.g. an AttributeGenerator or BeforeProvisioning Rule), you can store dynamic configuration in the source’s connectorAttributes and access it from the rule:

PATCH /v3/sources/:id

[
    {
        "op": "add",
        "path": "/connectorAttributes/ruleSourceIds",
        "value": [
            "id1",
            "id2",
            "id3"
        ]
    }
]

In the rule code:

Object ruleSourceIds = application.getAttributeValue("ruleSourceIds");
if (ruleSourceIds instanceof List) {
  List sourceIds = (List) ruleSourceIds;
  // ...
}

The Services Standard IdentityNow BeforeProvisioning Rule uses the same methodology to retrieve its dynamic configuration.

Similarly, in rules that provide a field variable (e.g. AttributeGenerator), you can store dynamic configuration in the ProvisioningPolicy field’s attributes map:

{
    "name": "Account",
    "description": null,
    "usageType": "CREATE",
    "fields": [
        {
            "name": "sAMAccountName",
            "transform": {
                "type": "rule",
                "attributes": {
                    "name": "My AttributeGenerator Rule"
                }
            },
            "attributes": {
                "ruleSourceIds": [
                    "id1",
                    "id2",
                    "id3"
                ]
            },
            "isRequired": false,
            "type": "string",
            "isMultiValued": false
        },
        ...
    ]
}

In the rule code:

Object ruleSourceIds = field.getAttribute("ruleSourceIds");
if (ruleSourceIds instanceof List) {
  List sourceIds = (List) ruleSourceIds;
  // ...
}
3 Likes