Hello Sailors,
In case there are unused attribute assignments or sticky entitlements that can cause auto provisioning failures.
In IIQ these assigned attributes are referred as "sticky entitlements" - these are entitlements directly added via LCM that have a source="LCM". The entitlements are considered "sticky" as IIQ sees these has been manually added to the account so certain processes do not remove these entries. A direct removal of these entitlements via LCM removal request would clean these AttributeAssignment entries up. Or a revoke via certification would do the same.
In order to remove these sticky entitlements you can run the following rule as a pre-refresh rule or you can run it as a Rule Runner Task as sometimes we have a Leaver Event that disables the application account link but does not remove these sticky entitlements. This rule will clean-up these sticky entitlements and the logic it does is by checking that the application link exists for that identity and if not remove the AttributeAssignment object for that application so that they are not auto-provisioned when we do a Identity Cube Refresh with the provision assignment option enabled.
If you are using the Pre-Refresh Rule then in the Identity Cube Refresh Task add this xml tag - <entry key= "preRefreshRule" value = "[Refresh Rule Name]" />
Below is the rule:
----------------------
import sailpoint.api.IdentityService;
import sailpoint.object.Application;
import sailpoint.object.AttributeAssignment;
import sailpoint.object.Link;
import sailpoint.tools.Util;
// Sniff the AttributeAssignments and look for any pointing to a Link that doesn't exist. Set the nativeIdentity to null on said assignment
// and let it fall away naturally
IdentityService iSvc = new IdentityService(context);
boolean dirty = false;
List assignments = identity.getAttributeAssignments();
if (!Util.isEmpty(assignments)) {
for (Object assignmentObj : assignments) {
AttributeAssignment assignment = (AttributeAssignment)assignmentObj;
Link matched = null;
Application assApp = null;
if (assignment.getApplicationId() != null) {
assApp = context.getObject(Application.class, assignment.getApplicationId());
}
String instance = assignment.getInstance();
String nativeIdentity = assignment.getNativeIdentity();
if (nativeIdentity != null && !"".equals(nativeIdentity.trim()) && assApp != null) {
matched = iSvc.getLink(identity, assApp, instance, nativeIdentity);
}
if (matched == null) {
assignment.setNativeIdentity(null);
dirty = true;
}
}
}
if (dirty) {
context.saveObject(identity);
context.commitTransaction();
}
Hope this might help someone who run into the similar scenario.
Thanks!
Sumit Gupta
Good one Sumit...
This is useful for any provisioning apps which are partially managed through IdentityIQ.
In other words,
1. if access/security is provisioned to end system via identityIQ for an user (this access info get stored as sticky entitlement in identityIQ object),
2. if user access is updated on target end (managed on target end)
3. Daily/Weekly aggregation fetches the updated account details into IIQ
4. Daily/Weekly identity refresh on that profile - tries to auto-provision the initial security/entitlement as it is stored as sticky entitlement with the initial assignment
Above preRefresh rule helps in fixing these kind of auto-provision errors.
It is a good idea to create a population for such partially managed apps and run the refresh on that population with preRefresh rule embedded.
This will avoid the overhead on the entire population if refresh task is intended for all the identities in the system.
Hi
I'm getting the following errors when using this rule in 8.2p2. It worked fine in 7.3p3. Anything I should look at to fix this?
Thanks.
Pasha
2022-05-20T10:22:18,098 WARN RefreshWorker 7 engine.jdbc.spi.SqlExceptionHelper:137 - SQL Error: 0, SQLState: null
2022-05-20T10:22:18,098 ERROR RefreshWorker 7 engine.jdbc.spi.SqlExceptionHelper:142 - The result set is closed.
Caused by: org.apache.bsf.BSFException: The application script threw an exception: org.hibernate.exception.GenericJDBCException: could not get next iterator result BSF info: Sailpoint - Remove unused AttributeAssignments at line: 0 column: columnNo
at bsh.util.BeanShellBSFEngine.eval(BeanShellBSFEngine.java:197) ~[bsh-2.1.8.jar:2.1.8 2018-10-02 08:36:04]
at org.apache.bsf.BSFManager$5.run(BSFManager.java:445) ~[bsf.jar:?]
... 9 more
2022-05-20T10:22:18,144 ERROR RefreshWorker 7 sailpoint.task.IdentityRefreshExecutor:1624 - RefreshWorker 7 exception: The application script threw an exception: org.hibernate.exception.GenericJDBCException: could not get next iterator result BSF info: Sailpoint - Remove unused AttributeAssignments at line: 0 column: columnNo
sailpoint.tools.GeneralException: The application script threw an exception: org.hibernate.exception.GenericJDBCException: could not get next iterator result BSF info: Sailpoint - Remove unused AttributeAssignments at line: 0 column: columnNo
at sailpoint.server.BSFRuleRunner.runRule(BSFRuleRunner.java:219) ~[identityiq.jar:8.2p2 Build b9a7ae198e1-20220302-182712]
The fact that the Identity has the corresponding Link on the AttributeAssignments still doesn't make the AttributeAssignments valid.
Consider the scenario that someone has an Active Directory link with special AD groups, and the attribute assignments on the Identity gives access to these special AD groups. When the person's special AD groups gets removed outside of IIQ, IIQ will again try to give these special AD groups to the person.
Hello @chendra_alladi I think there is a typo in the supplied code. Can you please take a look? Identity is not defined
List assignments = identity.getAttributeAssignments();
@matthew_pahls I am not @chendra_alladi but I might know the answer
I believe, if you run it as a prerefresh rule in the refresh task, identity is available in the shell.
if you run it as a standalone rule, you need to provide the identity.
Thanks.
Pasha