Share all details related to your problem, including any error messages you may have received.
Hi Everyone,
We need to implement a restriction to prevent the generation of certification access reviews if there is already a pending review for the same user when user profile data changes hence Life cycle events trigger like Attribute Changes and Manager Transfer.
Objective is to streamline the access review process and avoid duplication by ensuring that users do not have multiple pending reviews simultaneously.
Normally the a certification (eg. manager cert) happens once in 3 months or once in 6 month… so that defines a long period for the reviewer to do the access review… I am not sure there is product specific solution for this, but I can recommend a process oriented solution for your problem…
Configure a certification phases period limit, set expiration time for each phases, set reminders… make sure there is enough time gap between the certs to avoid the overlap.
I recommend to use the same template for each certification for every quarter or bi annual, which ever one your organisation needs… Usage of same template over definite time interval will eliminate your problem
If there is product specific solution I would like to know too…
If you found this post helpful, kindly mark it as solution
We can write a rule and schedule it (every 5 minutes or so) to check active certifications (getPhase())->then getting their certifiers(getCertifiers()) and iterating over each Identity on that list getting certifications linked to that identity and deleting that item if redundant.
Can’t say if my suggestion would work but if I had to do it I’ll do it this way.
This would need testing and research on different methods in java docs.
I would create an Exception rule which will remove the Certification Item from the certification when already in another certification.
Using the option Automatically Sign Off When Nothing to Certify will automatically close the certification when all items are excluded.
This will still create the certification for audit purposes and the exclusion will state why it is closed (also enable Save Exclusions).
You can use the following code snippet so find if there is already a non-completed certification for the identity (This can be extended to look for the attribute.). Based on this snippet you can create the exclusion rule for your certification.
import sailpoint.object.*;
import sailpoint.api.IncrementalObjectIterator;
String identityName = "Name of the Identity";
QueryOptions queryOptions = new QueryOptions();
queryOptions.addFilter(Filter.ne("complete",true));
IncrementalObjectIterator certs = new IncrementalObjectIterator(context, Certification.class, queryOptions);
int recordCounter = 0;
boolean found = false;
while (certs.hasNext()) {
Certification cert = (Certification) certs.next();
recordCounter++;
List entities = cert.getEntities();
for (CertificationEntity entity : entities) {
if (identityName.equals(entity.getIdentity())) {
// maybe perform extra checks to see if CertificationItem is for the attribute which has been changed ...
found = true;
log.error(cert.getName());
break;
}
}
if (found) break;
if (0 == (recordCounter % 10)) {
context.decache();
}
}
context.decache();
When you have created the Exclusion Rule, be sure to update the certification definition of your Certification Event with the options mentioned above.
I hope this will bring you a step further to meet your requirement
I believe exclusion rule is what you can use. Check if the user has any pending certification. If yes, iterate through each item(Exception, Bundle or Account only) for the certification being generated. Compare the items and then if both items in the existing certification and certification being generated is same exclude the item. Remold Krol has already explained other configurations required. You can also add some custom Audits if required for exclusion reasoning.
We have similar implementation . As part of the transfer process which is based on the certain identity attribute from the HR system we trigger the custom workflow .
Addition identity attribute named " transferInProgress is created .
in the custom workflow we check we check the value of above attribute ,
if the transferInProgress is null
{
// code
set transferInProgress as true ,
trigger the access review
}
if transferInProgress is true {
//code
skip access review
}
and before the workflow completes we set the value as null again .
Preferences are easier for transient values, as no additional identity attribute is needed (and to be configured) and you can pick any String for the name.
We have used the same for sending leaver mails (14, 7 and 3 days before contract end date), to make sure no duplicate emails are sent when the process is started multiple times per day
we have scenario if some sets of attributes changes for the user , we need to trigger a access review process which goes to the manager .
below is the setep
Addition identity attribute named " transferInProgress is created .
in the custom workflow we check we check the value of above attribute ,
if the transferInProgress is null
{
// code
set transferInProgress as true ,
trigger the access review
}
if transferInProgress is true {
//code
skip access review
}
and before the workflow completes we set the value as null again .
I’d be very nervous about iterating over Certification objects like that. They can be large, and if you just need to check for existence, HQL or context.countObjects avoids the need to send a bunch of data to the to the application server for processing.
Very, very, roughly:
QueryOptions qo = new QueryOptions();
Filter entityFilter = Filter.and(Filter.eq("targetId", identityId), /* Filter for status */);
return context.countObjects(CertificationEntity.class, qo) > 0;
If the status of the CertificationEntity gets updated before the Certification is complete (I don’t recall if it is considered done before the Certification is signed off), then you should be able to join CertificationEntity with Certification using either an implicit join (something like Filter.eq("entities.targetId", identityId) or a Filter.join, and then include a filter on Certification status.