Apologies for a lot of questions, really appreciate any guidance from you Experts!
We are transitioning from IIQ to ISC and I have an issue where a large number of the Identities coming from the HR source are not being created. It appears to me that it ‘might’ be because these Identities have a blank ‘uid’ on the HR source.
Would a blank(required) uid on the HR source cause the Identity to not be created in ISC?** Shouldn’t it still be created with an error or something?
In IIQ we had an Identity Creation Rule that would handle this type of situation
Would something like an ‘IdentityAttribute’ Rule be able to generate the userName if it was found to be blank?
If so, would this work in ISC and would it be account.getAttribute or identity.getAttribute?
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Rule name="Corp_IdentityCreation_UserName" type="IdentityAttribute">
<Description>If username is empty from HR - create username</Description>
<Source><![CDATA[
import sailpoint.tools.GeneralException;
import sailpoint.object.*;
import sailpoint.api.*;
import org.apache.commons.lang.StringUtils;
String userName = "";
//Create new username if the account doesn't have one
if( (null==account.getAttribute("CORPUserName") || ((String)account.getAttribute("CORPUserName")).isEmpty()) ){
//Use first letter of the PreferredName/FirstName + first letter of the LastName + EmployeeID to create new username
if(null!=account.getAttribute("PreferredName") && !((String)account.getAttribute("PreferredName")).isEmpty())
userName = userName + ((String)account.getAttribute("PreferredName")).substring(0,1);
//Use first letter of FirstName if PreferredName is not present
if((null ==userName || userName.isEmpty()) &&
(null != account.getAttribute("FirstName") && !((String)account.getAttribute("FirstName")).isEmpty())
){
userName = userName + ((String)account.getAttribute("FirstName")).substring(0,1);
}
if(null != account.getAttribute("LastName") && !((String)account.getAttribute("LastName")).isEmpty())
userName = userName + ((String)account.getAttribute("LastName")).substring(0,1);
if(null != account.getAttribute("EmployeeCode") && !((String)account.getAttribute("EmployeeCode")).isEmpty())
userName = userName + account.getAttribute("EmployeeCode");
if( userName.isEmpty() || null == userName ){
log.debug("Exception: Error in Rule_CORP_HR_Identity_Creation_Rule. unable to determine the userName");
}
else{
log.debug("Determined userName for Identity with EmployeeCode "+account.getAttribute("EmployeeCode")+" : "+userName);
return userName;
}
}
]]></Source>
</Rule>
I assume if this is all the direction I should be going and the rule looks OK (Approved by SailPoint??) it would show up in the Identity Profile mappings as a Transform for UserName?
Upon further investigation and a larger sampling of the identities that are not showing up - ends up it is not the UserName issue that I thought it was.
I’m not sure at this point why ~10% of the Identities are not aggregating into ISC.
If/When I figure it out, I’ll post here in case some other poor individual is ever searching for the same issue.
I think we need some additional info here. What is the HR source of truth in this case? What does your Identity Profile mapping look like, at least for the required attributes? Are the accounts aggregating into the source? If so, are they correlating to some other identity rather than creating their own identities, or are they just showing as uncorrelated in the authoritative source?
Now that I’ve gathered more detailed information on the missing Identities it does indeed appear to be userName related. There are two scenarios that seem to be stopping the accounts from aggregating and creating an Identity.
userName is blank in the HR source
userName has already been taken by another Identity
Many of these accounts are for inActive/Terminated Identities.
In IIQ we use an IdentityCreation Rule that will derive username and/or email if not present in the HR source when creating the Identity Cube.
It also appears that IIQ had been creating a userName based on displayName if the userName was already in use. I’m trying to find where the logic for that is coming from but haven’t found it yet.
Would my best option be to create a transform for userName in the Identity Profile mappings that will check if userName exists and apply it but if it is not found it would then create it based on some logic and apply it to the newly created Identity?
That is kinda what I was going for in the above code snippet.
The accounts that are not aggregating - are not showing up as uncorrelated, they just are not appearing in the system.
okay, so this makes sense then! if you look at the documentation, username must be populated with a unique value for all identities, so if the mapped attribute is null or not unique, that would explain it! the best thing to do would be to map the User Name (uid) Identity Attribute to something guaranteed to be unique, like Employee Number or something. calling it User Name is a little confusing - it’s their sailpoint username if they log into sailpoint, but otherwise does not need to be their username for downstream systems. and if you have SSO configured, they don’t even need to ever see/care about/know their username.
one thing you could do here is write a transform that concatenates a couple of values together to get a unique value - join their first name, last name, and employee number, or something like that (just make sure you use firstValid transforms to account for folks who don’t have a value in one of the fields!).
Not sure if this will help, but have you tried changing Identity profile priority to some lower value, or trying any different values, and then perform aggregation?