There are various times when an IdentityIQ installation may need to programmatically request that a Role assignment be removed from an Identity. One example would be specific types of transfer or leaver workflows that must immediately remove certain role assignments. The best practice for how to do this has changed over the years. Significant changes were introduced with the advent of changes in the Role management APIs in the 6.3 and newer releases to support assigning a Role to an Identity multiple times. This all raises an important question: How should you remove (or de-assign) a Role from Identity via the API?
Let's start with what not to do. There are many public methods available on the sailpoint.object.Identity object that look like they would be useful for dealing with role assignment methods. These include:
While these may have worked in earlier releases of the IdentityIQ they are not forward compatible with current or future releases of the product. Please do not call these APIs directly from custom BeanShell code or workflow code. SailPoint reserves the right to remove these methods from the public API or deprecate them in a future release. Many implementations that call these methods fail to lock Identity objects before committing changes.
What method should be used? The best practice is that you should treat a Role addition or removal like an LifeCycleManager (LCM) request. This means conceptually a role addition has a requesting party, a target identity on which the role will be removed, and some other meta data. That means you should construct a provisioning plan requesting the removal of what role(s) you want removed from the virtual application named "IIQ". The "IIQ" application is an application that can be used to make changes to an Identity's assignments inside IdentityIQ itself.
There is a distinction that can be made when removing Role assignments from an Identity. One method would be to "Remove the Role/Bundle assignment, but leave the entitlements that came from the role on the user's accounts". Another method would be to "Remove the Role/Bundle assignment, and walk down the tree of user's accounts and send off provisioning events to remove all of the entitlements supplied by that Role from from the user's accounts". This conceptually a "shallow removal" versus a "deep removal". The former is quicker and happens in IdentityIQ's database and the latter may expand to include many applications and take time for provisioning events to process.
There are a couple of ways to approach the best practice in code. One is short-winded and good for simpler circumstances but provides less visibility in the UI for what change took place. The other is longer-winded and better for circumstances where you want to see more of a paper-trail in the user interface. The longer winded method creates formal IdentityRequest objects that can be seen in the user interface under the Manage -> Access Requests menu screen.
Let's look at the shorter example first. This example is useful if you want to programmatically remove a role without approvals, email notifications, or the record of an IdentityRequest being left in the system. The code block for this approach is fairly easy.
String identityName = “mary.johnson”;
ProvisioningPlan plan = new ProvisioningPlan();
plan.setIdentity(context.getObject(Identity.class, identityName));
plan.add(“IIQ”, identityName, “assignedRoles”, ProvisioningPlan.Operation.Remove, “Some Role Name”);
Provisioner p = new Provisioner(context);
// if you want to remove the assignment without de-provisioning the entitlements set this
p.setNoRoleExpansion(true);
p.execute(plan);
You could think of this as a lightweight implementation. Many installations require a more feature-rich implementation that can be seen as an IdentityRequest much later on, days after the request was submitted. Attached is a fully functional example tested in a lab system that creates a Provisioning Plan for the Role Removals, then uses the Request Processor to launch a Workflow in the background to remove the Role(s) from the target Identity. This example provides all of the features for a completely searchable, viewable, and audit-able paper trail of why a Role was removed from an Identity.
The attachment sets the "approvalMode" to "none", which like the example above, disables approvals for the removal. If you want to require approvals for removing access then you will want to change this feature of the attached example.
I'm curious if this technique can also be used to remove AttributeAssignments. I'm guessing one would need to use a different attribute name than "assignedRoles" in the provisioning plan, but I'm not certain what. "assignedEntielment", or "assignedAttribute", something else? I am having a maintenance issue with some existing code that explicitly uses one of the "DO NOT USE" methods in Adam's initial message, but am at a bit of a loss for a replacement.
Set the "assignment" attribute to true in your attribute request
What is the use of negativeAssignment attribute?
Hi team,
The rule runs perfectly well in IIQ 7.3p2. I do want to change some information that is related to the executed workflow and it is the requester. I want it to show, as the requester, the name of a specific identity instead of "RequestHandler". Is there anything I need to add or change in the provisioning plan or in the attribute request definition to achieve this?
Thank you.
Hello,
We are facing a situation where the use of a ProvisioningPlan seems to be not possible.
In the Account Aggregation code of a WebService connector, if the Identity still doesn't exist in IIQ, how can we create a ProvisioningPlan to add him the AssignedRules?
The ProvisioningPlan.setIdentity() won't work because we don't have the identity, and the Aggregation->Creation Rule has an "identity" argument but is just temporary, I mean is not persisted.
Thanks a lot
@adam_hampton , I remember when I use the snippet below:
String identityName = “mary.johnson”; ProvisioningPlan plan = new ProvisioningPlan(); plan.setIdentity(context.getObject(Identity.class, identityName)); plan.add(“IIQ”, identityName, “assignedRoles”, ProvisioningPlan.Operation.Remove, “Some Role Name”); Provisioner p = new Provisioner(context); // if you want to remove the assignment without de-provisioning the entitlements set this p.setNoRoleExpansion(true); p.execute(plan);
, it used to work in IIQ8.0 and when i upgraded to IIQ8.4, error is occurring. So did anything changed?
@adam_hampton My bad. After doing some reverse look on the object, realized that the Rule object is corrupted. So when the snipped is used in a fresh rule object, it worked as expected. All good. Thank you!