This has been a long time coming!!! This has been my personal goal to drive this and to get help to build something for the community. Thanks for the great internal support this vision is finally coming true for me!!!
I am not a coder and definitely have 0 knowledge on Angular. But just have been looking and improvising on some existing codes after building a framework with someone who had the know-how. Have had a great support team to help build with me. Weekends, nights.. all sweat and blood 🙂Â
NOTE:Â This application is not developed, maintained or supported by SailPoint. It is built and based on a community effort. We are hoping people will contribute and help it grow.
About the tool
The goal of this project was to lessen the pain we saw in the field during deployment and go-live and by clients during daily op. I also wanted to drive the goal of a GUI model for easy and codeless interaction for end users for some basic tasks.
In an ideal world, wish we had dedicated time and knowledge on how to keep building on this but…
We are looking for (list is not exhaustive)
Help from internal and external community if they are interested in spreading the word
Help from keen internal and external community to help us build more features and extend existing ones.
GitHub and Actions know-how to help management and auto build / deploy / version et al
Help us make the Angular framework better and plug holes if any.
Help us enhance it (pagination, current build documentation / standardizing and refactoring code et al .. list is endless)
Testing, finding, and reporting and hopefully help fixing bugs – we are bound to find lot of issues to being with as its very new and not many people have used it. Please use in sandbox environment first.
Looking for contributors for the repo to help us set it up properly
Features
Current Feature list is
Find Multiple Accounts in source and download report
Bulk Manage Roles (Enable/disable/mark unmark as requestable/delete)
Bulk Manage Source Owners
Misc
Check and Set Org Time
Screenshots
Technical
It is an Angular app and using Electron to build for various environments. There is some technical how-to in the readme file. Currently hosted on GitHub repo and open source with MIT license.
I really hope this tool helps you in some way and feel free to enhance it and spread the word!!!
Anyone well versed with IDN Rules will know that there has been some historic limitations on what attributes we can and can’t use for uniqueness search or for other such methods. We were generally tied to “Account ID” and “Account Name” attribute in each source which were indexed in the DB which could be used in rules to do so.Â
Workaround till date had been to promote these attributes to an identity attribute and index them (which again had limitations of it own in terms on number of attributes and size of attribute).
Now we have a way to do this. Personally been involved with the product team and engineers in getting this shaped and delivered so a bit proud of this work. It is a great first start and will help you in doing so many use cases much simpler now.Â
Lets take a use case and a walkthrough on how you can set this up
Use Case – I
We want to generate a new email address which must have a unique prefix (firstname.lastname@) by checking against the “mail”, “userPrincipalName”, “proxyAddresses” attributes across 3 x AD connectors.Â
Note: Sources don’t have to be AD explicitly and can be virtually any source (AAD, ServiceNow, Okta, Workday etc)Â
Design
Now anyone who has worked with rules before would have known that this use case was not very easy to implement. You would have to promote these attributes, index identity attribute and then use it in the rule. Now we can create searchable attributes in the backend via API and use these in the rule.Â
High Level Steps are
Identify Source ID and attributes
Create Searchable Attributes
Do an unoptimised aggregation if source already exists (like production tenant) to populate these searchable attributes.
Use new methods in rules to search for uniqueness
Identify Source ID and Attributes
Now we have 3 x AD source in our design. For each of them we need to get their sourceID. You can fetch them with an API call
Get Source ID
1
GET{{api-url}}/cc/api/source/get/{{source-id}}
Where
{{api-url}}: This is your tenant URL in form of https://tenantName.api.identitynow.com
{{source-id}}: This is the number you see in your browser URL when visiting the source via UI
In the response you will get an externalId with a value like 2c9180867745f3b10177469563be7451d
Gather the externalId for all three sources you want to build it for.Â
Create Searchable Attributes
Now when you have all the SourceID’s we need to map and create searchable attributes. We will design 3 attributes (one for each – mail, userPrincipalName, proxyAddresses). It takes care of multivalued attributes as well (like proxyAddresses). The below table explains the designÂ
Once done for all sources, the search attributes get populated in the backend. Currently you can’t check them with the UI or API calls. Any new accounts which get created after this or come as aggregation (delta or full) will automatically keep updating the search attribute. So once set, you don’t have to do anything. Also new account created is populated immediately. So no need of aggregation of it. So if you are creating multiple users in concurrent – uniqueness check will still capture the previous value calculated – no need to wait for aggregation.
Use New Methods in the Rules
Our IDNRuleUtil guide has been updated with few new methods. Two in particular which use these attributes areÂ
attrSearchCountAccounts(): This will be helpful to use for uniqueness search
attrSearchGetIdentityName(): This will be helpful in say a correlation rule.Â
The link above has a bit more technical in-depth on what parameters are required by these methods and what is the return. But I will show you how to use the attrSerachCountAccounts() method in an example of uniqueness search.Â
AttributeGenerator Rule
Uniqueness Search Rule
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
importsailpoint.object.Identity;
importorg.apache.commons.lang.StringUtils;
List proxyAddressSources=newArrayList(Arrays.asList(newString[]{
"2c9180867745f3b10177469563be7451d",
"2c9180867745f3b10177469563be7451e",
"2c9180867745f3b10177469563be7451f"
}));
List upnSources=newArrayList(Arrays.asList(newString[]{
"2c9180867745f3b10177469563be7451d",
"2c9180867745f3b10177469563be7451e",
"2c9180867745f3b10177469563be7451f"
}));
List mailSources=newArrayList(Arrays.asList(newString[]{
Will short type the logic what I have followed here.Â
Create a list of 3 attributes with sourceID in them. This is required to pass the list to the new method.
Get the firstName and lastName from identity attribute, sanitise it and pass it to generateUniqueEmail() method
emailSuffix is also brought from identity attribute. This logic is already done via Transforms on what user email domain or suffix is suppose to be
In generateUniqueEmail() create a emailPrefix attribute and call isUnique() method.
isUnique() is where the magic happens
We are using StartsWith option (there is Equals also available). Reason being all the data coming from AD will be in some form of “[email protected], [email protected]”. We want to match “firstname.lastname@” only as we don’t care about exact match or equals match. Remember both are case-insensitive checks.
First check with proxyAddressSources in the idn.attrSearchCountAccounts() call
Here we have appended SMTP / SIP to do a startsWith check as we know that these are the known values we need to check in proxy address. We don’t have a contains. Also since its case-insensitive we don’t need to worry about camel casing or other such things. Data normally looks like “smtp:[email protected]” , “SIP:[email protected]”.
There are other such prefix found if proxyAddress attribute which we didn’t care about check but if your use case does, just add them and search as above.
If return == 0 means nothing is found, thus unique and move on to next check
Else isUnique == false and will return that value
Else check with upnSources source. Same logic as above
Else check with mailSources source. Same logic as above
If no account found here, isUnique is set to true and thus isUnique() has passed and the new email address is generated
If still a value is found, isUnique is set to false and thus isUnique() failed and new iteration starts
Max Iteration is set to 99 and then fail
Use Case – II
Rehire an account who comes back after 5 years with the same AD account.Â
Design
Now the account could be sitting as an uncorrelated account in IDN and we want to resurrect it. We can only search against the accountID or accountName as discussed previously and say if the correlating factor is employeeID which is not a part of either of these attributes.
Correlation Rule
Correlation Rule
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
importsailpoint.object.*;
importjava.util.*;
importorg.apache.commons.lang.StringUtils;
List adSource=newArrayList(Arrays.asList(newString[]{
We create an attribute like above called “allADEmployeeNumbers” and populate that with AD – employeeID (or whatever you may have)
We do an unoptimised aggregation to populate the search attribute
On an aggregation of an authoritative source, we have a correlation rule attached
It grabs the “employeeNumber” coming in from the source
Calls attrSearchGetIdentityName() to find that employeeNumber in the searchable attribute.
If found it returns an IdentityName of the cube and this can be used to correlate
If not found it returns an empty returnMap i.e. creates a new identity.
During design we took care of the following scenarios
It should return null if it found multiple names or no names.Â
It should return one identityName even if multiple links were found but single identityName (i.e. say if you had multiple employeeNumbers in links but all are attached to cube). Like in a daisy chain scenario.
Possibilites
You can see the power of these new methods and how you can use them. Some of my thoughts here on possibilities.Â
We can daisy chain them like above to search for multiple attributes in multiple sources as per your pattern.
We can use these for more attributes from accounts without the need to identity attribute creation and hitting limits on indexing.
Resurrections with attributes not indexed is also now pretty easy.Â
Hope this really help you in your future implementations!!!
As you will see currently the supported objects are limited (ETS / Rules / Sources / Transforms as I type this) but that list is set to grow as the API solidifies. The documentation is quite good and comprehensive on what you can do and how to. You can also take this to next step and incorporate / build your own CI/CD process to migrate your tenant config from sandbox to production.Â
Disclaimer: This is still beta endpoints so please do test out the process and give feedback to SailPoint
In my previous guide I had mentioned that how to deploy and attach rules in IDN. But there is a big change to this announced.
Client can now directly attach what we call as “Connector Rules” into their IDN tenants without going through the rule review process. Reason behind it
Connector-Executed Rules or Connector Rules are rules that are executed in the IdentityNow virtual appliance, and are usually an extension point of the connector itself. The rules are commonly used for performing complex connector-related functions, and likewise are very specific to only certain connectors. Because these rules execute in the virtual appliance, they do not have access to query the IdentityNow data model, or fetch information from IdentityNow; instead they rely on contextual information sent from IdentityNow. Connector-executed rules may also have managed connections supplied in their contexts in order to support querying end systems or sources. While these managed connections may be used, making additional connections or call-outs is not allowed.
This should make it much easier and faster for clients to upload and modify rules themselves. The rule types allowed are