Monday, January 15, 2018

Déjà Vu - IGI Handling of AD Dormant Accounts

I know I had this problem years ago with ISIM. Why do I have this problem again with IGI?

Years ago, the ISIM adapter for Active Directory would reconcile the Last Logon Date that was specific to which ever Domain Controller the adapter connected to. That meant, of course, that the REAL last logon date for a user was not being reconciled and any life-cycle rule built to query that attribute and act upon the value contained therein would, in all probability, cause a major "hoo-ha".

IBM resolved the issue by adding erADLastLogonTimeStamp which returned the domain replicated last logon date (albeit, the date could be +/- 14 days in accuracy for reasons which Bill Gates would be best to explain).

IGI is a new product but uses the ISIM adapters. However, the internal IGI mapping for of Last Logon is using the old erADLastLogon date rather than the slightly more reliable erADLastLogonTimeStamp.


What are these crazy kids thinking? Did the ISIM guys not talk to the IGI guys? (That said, I've checked the latest resource.def file for the ISIM adapter and I'm disappointed to report that the erLastAccessDate mapping is set to erADLastLogon!).

In any case... if you want to run any kind of dormancy rule on Active Directory accounts in IGI, make sure you do this BEFORE you reconcile your service:

update itimuser.entity_schema_mapping set custom_attribute_name='eradlastlogontimestamp' where custom_class_name='eradaccount' and system_attribute_name='erlastaccessdate';

This little gem will ensure that the correct AD attribute is used as the last access date rather than the pitiful erADLastLogon attribute which is borderline useless.

Maybe IBM will update their configuration and resource.def file and documentation at some point (again).

Tuesday, December 19, 2017

IGI Default Account Attributes

DISCLAIMER: This article is not applicable to IGI v5.2.3 or later!

Setting account defaults in IGI is rather like setting account defaults in IBM Security Identity Manager (ISIM). For those familiar with both products, you will recognise that the ISIM screens were copied/pasted into the IGI platform with very little alteration. (One difference, of course, is the ability to set enforcement on attributes, but dealing with that is one for another day!)

Provisioning a new account can be tricky to troubleshoot, however. It seems that the logging levels can be less than helpful in certain circumstances. Consider the dreaded java.lang.NullPointerException! This can be thrown by the provisioning engine when the account defaults code is problematic.

Consider that we have a need to set an attribute in a provisioning target to the value of ATTR2 on our identity record, but only when ATTR1 is set to Y. You might consider using the following code:

if (subject.getPropertyAsString("attr1") == "Y") {
  return subject.getPropertyAsString("attr2");

The code looks great, but this code will throw our dreaded NPE in certain circumstances. Not only that, but our logs won't actually tell us which attribute and therefore which section of code is causing our NPE. Why does this happen?

Well, the provisioning engine MUST get an object returned from our code in ALL circumstances and the above code only returns a value if ATTR1 is set to Y. To avoid our NPE, we need to complete the code as such:

if (subject.getPropertyAsString("attr1") == "Y") {
  return subject.getPropertyAsString("attr2");
} else {
  return "";

The addition of a return statement within the ELSE clause will ensure we always return something. Our NullPointerException won't appear again...

Monday, September 11, 2017

IGI - Careful With Those Hierarchies

One of the beauties of IBM Security Identity Governance & Intelligence (IGI) is the ability to create custom "hierarchies" which I've discussed elsewhere in this blog. So much power, yet so much frustration too. These things need a LOT of tender love and care.

How so? Well, for two reasons:

  • Batch only rebuilds rather than "on-the-fly" insertions; and
  • Non-completion of a rebuild

Batch Only Rebuilds
Hierarchies are rebuilt by a batch process handled within the Task Planner. This rebuild iterates over every PERSON object in the data repository and re-evaluates the hierarchy location for each and every user which is fine for re-synchronisation of a hierarchy against the PERSON objects.

But if a new PERSON appears in the system, they won't inherit their birthright entitlements until the hierarchy is regenerated. If there are a large number of PERSON objects in the system, a hierarchy rebuild may take some considerable time and may be scheduled to only execute once a day! Hardly ideal.

Fortunately, the upcoming latest and greatest version of IGI is supposed to address this inadequacy and should support "on-the-fly" insertion of PERSON objects into any hierarchy (and not just the Organisational Unit Hierarchy).

Non-Completion of Rebuilds
The lack of "on-the-fly" insertions of PERSON objects into a hierarchy is doubly troublesome because a hierarchy rebuild may fail! Remember, a rebuild iterates over every PERSON object in the underlying repository. A failure to process any one of those PERSON objects could result in the hierarchy rebuild stopping.

In other words, in a system of 20,000 people, a failure to process person number 19,999 will mean that person number 20,000 will not get processed at all! To put that another way, the system does not FLAG the failure to process a person and basically abandons processing all subsequent users.

Oh dear! So what can cause a failure and should our custom hierarchy construction code be more robust? Unfortunately, our custom hierarchy construction code probably has nothing to do with any failure as there are a myriad of other reasons why a hierarchy build would merely stop (after a bout of hissy-fitting). Take these two examples:
  • Insertion of a user into a hierarchy triggers the creation of an account as a result of a birthright entitlements attached to the hierarchy node; but the account creation throws an error because it attempts to re-use the Master UID of the user to create the account but an account with that ID already exists!
  • Insertion of a user into a hierarchy triggers the addition of an entitlement to a user's account as a result of a birthright entitlement attached to the hierarchy node; but the user seems to already own two accounts for that service - something which should not be possible with IGI in the current version (v5.2.2) but seemingly IS possible under certain circumstances!

In other words, it doesn't matter how robust your hierarchy construction code is, the quality of the underlying data could throw quite a major spanner into the works! Of course, a better approach would be for the core IGI engine to handle such issues and at least move on to the next PERSON object to be processed. Maybe in the next release!

Meantime... take care of that data! Get a handle on your orphan management processes and check for duplicates. The following  SQL command will help you with that particular diagnosis:

select pw.pwdcfg,pw.person,p.code,count(*)
from pwdmanagement pw
left join person p on
where pw.person is not null
group by pw.pwdcfg,pw.person,p.code
having count(*)>1;

Sunday, August 13, 2017


I've been writing this blogs for many years now and I typically use it as a means of recording snippets of information that ideally I would like to refer back to and snippets of information that I think others would be interested in.

So, what are you guys interested in?

Well, the beauty of running a blog like this for so long is that I get to see which posts are popular and which are not! I get to see which products you guys are using and abusing. And I can tell you that the popularity of these IBM security products can be easily ranked. In reverse order (by popularity):

IBM Security Identity Governance & Intelligence (IGI) is the new kid on the block so it is understandable that not many people are interested in what I have to say about IGI. Maybe, over time, this will change. Fingers crossed!

IBM Security Access Manager (ISAM) has been around forever but it seems that nobody is interested anymore. That's probably a sign that organisations have shifted their focus elsewhere and that federated security (which ISAM handles really well) is the way forward and freebie tools that are SAML and OpenID:Connect ready are preferable?

IBM Security Identity Manager (ISIM) has been around forever too, but it has always been a heavyweight beast of a product that requires significant investment and therefore is used by huge organisations only. I don't know how many ISIM customers there are out there, but I'm guessing it is a dwindling list given that IGI is seen as the long-term replacement.

And then we come to IBM Tivoli Directory Integrator (ITDI). Of all the things I've ever blogged about, it seems that TDI generates the most interest - and by a country mile! As an example, the last time I mentioned TDI, it managed to gather more than 300 times as many page requests as everything to do with IGI put together! One single post!

TDI is still a tool I go to on a daily basis. It is truly wonderful and flexible and easy to get to grips with. Maybe I should focus more on TDI topics?

In any case, I'd be interested to hear from whomever out there reads the stuff that I write. What topics would you like me to cover? What products do you think deserve focus? Do you still find any of this information worthwhile?

I still hope there are plenty of you IBM Security specialists out there helping to deliver a smarter, more secure planet.

Monday, July 24, 2017

IGI Custom Reports - Best Practice Guide

A short and sweet "quick tip" update only, I'm afraid. Anyone looking to settle down to a long read will be sorely disappointed as my time is precious and this topic doesn't deserve lengthy discussion.

Creating custom reports in IBM Security Identity Governance and Intelligence (IGI) is a multi-step process:

  • Create a SQL query to extract data
  • Create a "Report" to structure the data according to your needs
  • Assign the "Report" to a user community

What happens if you need to update your report to include an additional data element, however? Unfortunately, IGI (as of v5.2.2) does not afford you with the luxury of updating your SQL query to grab the additional data element without deleting the report. What a pain.

My solution? Don't bother.

Well... I say don't bother. What I mean is that there is no need to update the SQL query in-situ.

A better approach might be to create a new SQL query with the additional data element, create a new report as required and associate the new report to the same user community as the old report. The old report can remain in the system although disassociating it from the user community would seem to be a reasonable final step to take.

When I create a custom report, I like to follow these steps:

  • Create a SQL query to extract data and add a version number to the name, i.e. "Stephen's Query v1.0"
  • Create a "Report" to structure the data according to my needs and add a version number to the name, i.e. "Stephen's Report v1.0"
  • Assign the "Report" to a user community, i.e. IGI Users Called Stephen

When I need to update the report, I follow these steps:

  • Create a SQL query to extract data and add a version number to the name, i.e. "Stephen's Query v1.1"
  • Create a "Report" to structure the data according to my needs and add a version number to the name, i.e. "Stephen's Report v1.1"
  • Assign the "Report" to a user community, i.e. IGI Users Called Stephen
  • De-assign the "Old Report" from the user community

Of course, an added benefit is that it is much easier to "roll-back" to the previous version of the report if necessary and I didn't have to delete anything.

NOTE: I would frequently prefix all my custom reports with some identifier which helps me differentiate custom reports from the pre-packaged reports. For example, when providing services to ACME Inc, I may prefix all my reports with ACME and I would NEVER customise a pre-packaged report, but rather create a new custom-version of the report instead.

Wednesday, April 05, 2017

IGI Report Building

IBM Security Identity Governance is undoubtedly a powerful tool. However, the documentation supplied with the tool could certainly do with some improvement and there is a desperate need for a lot more "technotes" to help deployment consultants get the best value out of the tool.

As an example, IGI ships with almost 100 canned reports but one important report that seems to be missing is a report listing all the orphan/unmatched accounts within the system.

Generating such a report should be a breeze using IGI's Report Designer module. But here comes another "however". The documentation doesn't really give you any kind of clue as to how the underlying database schema has been put together and therefore it is difficult to understand which tables, attributes and values should be used to construct such a report. It also doesn't help that in some cases, the naming convention used is somewhat confusing.

That said, here is how you might construct a simple Orphan Accounts report.

Step 1 - Create Query
Create a new query called "Orphan Accounts"  with the following as the SQL Query:

select as APPNAME,
  pwdm.code as USERID, as FIRSTNAME,
  pwdm.surname as LASTNAME, as EMAIL,
  pwdm.dn as DN,
  pwdm.lastlogin as LASTLOGIN
  #pmschema#.pwdmanagement pwdm
  left join t on pwdm.pwdcfg=t.pwdcfg
  pwdm.state > 0

This query pulls out the Application Name, User ID, First & Last Names, Email Address, DN and Last Login Date/Time for those accounts that are in an orphan/unmatched state. The STATE attribute having a value greater than 0 means that the account has not been matched to an identity.

Make sure that you you select the "Query Column" link at the bottom of the screen and click on IMPORT in order to be left with the following:

Step 2 - Create Report
Now, create a new report called "Orphan Accounts" using the query that you have just created.

Reorder the columns as necessary within the Columns tab. Under Additional Data, ensure that report output formats are selected. In this case, CSV and XSLX are great options.

Under the Localization tab, ensure the column names are assigned appropriate business friendly names.

Step 3 - Report Assignment
The report has now been built, but it needs to be made available to a set of users. Within the Report Designer, navigate to Configure > Assignment > Report/Dashboard -> Entitlement and select the report you have just created.

Now assign the user community to the report. When clicking on Add, you will be presented by a list of default administrative IT Roles rather than Business Roles. If you want to assign the report to a particular Business Role (i.e. Application Manager), then click on Filter, select Type and select Business Role to see a list of roles.

Once the report has been assigned to your business role, you can now log in to the Service Centre as a user with that Business Role entitlement and you will see the "Orphan Accounts" report available for execution.

Hopefully a comprehensive definition of the schema will be documented and made available at some point in the near future. Meanwhile, hacking around the SQL Query definitions that are provided out of the box is probably going to be your best option for constructing your own reports.

Monday, February 27, 2017

IGI Default Entitlements

Those of you who have downloaded the latest (and greatest) version of IBM Security Identity Governance (v5.2.2) are no doubt having a wonderful time with the new interface and the new features.

But like every new software release, one or two things may not behave quite like you expected them to.

As an example, the rule embedded within the USER_MOVE Rule Flow suggests that the moveUser method will move a user to a new Organisational Unit and automatically assign all default entitlements assigned to that OU. At least, the comments explicitly state that this is to be expected:
// Move the user assigning the default entitlements of the new OU
UtilAction.moveUser(sql, userBean, orgUnitBean);

Unfortunately, the result of this operation is somewhat disappointing. The user does indeed move... but new default entitlements are not assigned.

Checking a v5.2.1 demo image that I have, though, reveals the following additional code which does actually meet our expectations:

// Assign default entitlements of OU
EntitlementBean entBeanDefault = new EntitlementBean(); 

BeanList entsDefault = _OrgUnitAction.findEntitlementByOU(sql, false, entBeanDefault, null, orgUnitBean, null);
if (!entsDefault.isEmpty()) {
    for (int k = 0; k < entsDefault.size(); k++) {
        EntitlementBean role = (EntitlementBean) entsDefault.get(k);
        BeanList roles = JobRoleAction.find(sql, role);
        if(roles==null || roles.isEmpty() ) {
            throw new Exception("Role : " + role.getName() + " not found!");
        UserAction.addRole(sql, userBean , orgUnitBean , roles , null, null, false, false);

NOTE: The following will need adding to the Package Imports:
import com.engiweb.profilemanager.common.ruleengine.action.reorganize._OrgUnitAction
import com.engiweb.profilemanager.common.ruleengine.action.JobRoleAction