cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

IdentitySelectors in the IdentityIQ user interface

IdentitySelectors in the IdentityIQ user interface

 

An IdentitySelector is a way to test an identity against a set of criteria. This is a matching process, not a searching process. In other words, the criteria will be evaluated per identity while iterating over a list of identities. The criteria therefore do not need to be indexed or searchable and can even be complex expressions. The outcome of the matching process is a boolean true or false value indicating whether to include or handle the identity.

 

There are several places within IdentityIQ, where an IdentitySelector is or can be used to filter identities.

 

Some places are hidden, working in the background (see for example Controlling Identity Suggests with IdentitySelectors). Some are visible and configurable in the UI. Examples are:

  • Advanced polices ("Selection method", see Policies),
  • Automatic role assignment ("Assignment rule" in business roles),
  • Selection of included identities in Lifecycle Events and Certification Events ("Identities included").

 

Types of IdentitySelector configurations

There are five ways to configure an IdentitySelector:

  • Match List,
  • Filter,
  • Script,
  • Rule,
  • Population.

Apart from these options, sometimes the option "All" is presented. This effectively creates no IdentitySelector at all. In some other the option "None" is present. This also does not create an IdentitySelector. The part of the product where the IdentitySelector is used determines how the absence of an IdentitySelector affects the selection: match all or match none.

 

Match list

A match list based identity selector is very similar to an entitlement SOD policy, except:

  • There is only one filter set and,
  • Any account attribute can be used, even if it is not an entitlement.

 

The following image shows what a match list looks like in an advanced policy rule.

Edit_Advanced_Rule.png

 

The two filter sets of an Entitlement SOD policy can be simulated by making two groups and applying the And expression to these groups. This would look like the image shown here:

Cursor_and_Edit_Advanced_Rule.png

 

Filter

The "Filter" type of the advanced rule is a so called "CompoundFilter". The expression always starts with <CompoundFilter> and ends with </CompoundFilter>. The actual filter expression is a Filter or CompositeFilter. A CompositeFilter can combine multiple Filters. In addition to the Filter or CompositeFilter, an additional section <Application>...</Application> can be used to refer to application definitions which attributes are used inside the filters. The filters refer to the applications using a numeric code, starting with 0: the position of the referred application in the list. The numeric code is followed by a colon and the attribute to be compared, e.g.: 0:memberOf. Identity attributes are used without any reference. If the Application section is omitted, the full name of the application must be used, e.g.: ExampleApp:memberOf.

 

An example filter, representing the same filter as the Entitlement SOD policy example and the match list example, would look like:

 

<CompoundFilter>

   <Applications>

     <Reference class="sailpoint.object.Application" name="OpenDS"/>

     <Reference class="sailpoint.object.Application" name="Ubuntu"/>

   </Applications>

   <CompositeFilter operation="AND">

     <CompositeFilter operation="OR">

       <Filter operation="EQ" property="0:isMemberOf" value="cn=testgroup,ou=Groups,dc=pieters,dc=cx"/>

     </CompositeFilter>

     <CompositeFilter operation="AND">

       <Filter operation="EQ" property="1:group" value="iiq"/>

       <Filter operation="EQ" property="department" value="Software Testing"/>

     </CompositeFilter>

   </CompositeFilter>

</CompoundFilter>

 

 

An explanation of the CompoundFilter can be found in a separate document: CompoundFilter. More examples can be found in Examples of XML for a CompoundFilter in the UI.

 

Script and rule

Script and Rule are virtually the same. Both are BeanShell scripts and have the same input parameters and returns. The difference is where the BeanShell code is stored. In case of a Script based identity selector, the code is stored as part of the enclosing object (policy, role, etc.). In case of a Rule based identity selector, the code is stored in a separate Rule object and only a reference to this Rule is stored in the enclosing object.

 

For general information on writing BeanShell code refer to Writing Rules and Scripts and the BeanShell Developer's Guide for IdentityIQ.

 

The rule is supposed to return either true or false (boolean), where true means that a match has been found. In a policy rule, the script or rule may, instead of a boolean value, also return an object of type sailpoint.object.PolicyViolation. Returning null has the same effect as returning false.

 

Population

Probably the easiest variant of an identity selector is the population type. When this type is selected, only a drop down list is presented to select a pre-defined population.

 

Role_Editor.png

Any identity that is a member this population is considered a match for the identity selector. A population can be created by searching identities with the desired criteria in the advanced analytics and storing the result as a population.

Advanced_Analytics.png

Once the population has been created, it is marked as private. Go to Define > Groups > Populations and open the population. The private mark can here be undone.

Edit_Population.png

 

A downside of using a population for an identity selector may be that a population is rather static and cannot be changed easily. Once a population has been defined, it cannot be changed through the web user interface, but only by editing XML directly. An end user would have to create a new population and update the identity selector if the population definition needs to be changed. Removing a population and creating a new one with exactly the same name will break the identity selector definition. The population must be reconnected to the identity selector.

 

Note: the text in this article has been derived from the wiki article on Policies and slightly rewritten to be more generic. The Policies article has been updated to point to this article.
Comments

Great article, Menno.  Here's an example from the IdentitySelectorConfig XML that shows how you can use Bean Shell to specify the Filter in an IdentitySelector:

            <entry key="Global">

              <value>

                <IdentityFilter ignoreGlobal="true" name="Global" order="Ascending">

                  <FilterScript>

                    <Script>

                      <Source>

                        

                          import sailpoint.tools.Util;

                          import sailpoint.object.*;

                          import java.util.*;

                                                  

                          QueryOptions qo = new QueryOptions();

                          Identity identity = context.getObjectById(Identity.class, loggedInUser);

                          boolean containsComma = false;

                        

                          // Strip out dots, commas, at-signs, etc.

                          for (int i=0; i &lt; parts.size(); i++) {

                            //if (parts.get(i).contains(",")) { parts.set(i, parts.get(i).replace(",", "")); }

                            if (parts.get(i).contains(",")) { containsComma = true; }

                            if (parts.get(i).contains(".")) { parts.set(i ,parts.get(i).replace(".", "")); }

                            if (parts.get(i).contains("@")) { parts.set(i ,parts.get(i).replace("@", "")); }

                          }

                          //System.out.println("parts.size() is: "  + parts.size());

                          //System.out.println("Parts Contains Comma: " + containsComma);

                          if(!containsComma) {

                            List filters = new ArrayList();

                            for (String part : parts) {

                              Filter nameFilter = Filter.ignoreCase(Filter.like("name", part, Filter.MatchMode.START));

                              Filter fnFilter = Filter.ignoreCase(Filter.like("firstname", part, Filter.MatchMode.START));

                              Filter lnFilter = Filter.ignoreCase(Filter.like("lastname",  part, Filter.MatchMode.START));

                              Filter emailFilter = Filter.ignoreCase(Filter.like("email",  part, Filter.MatchMode.START));

                              filters.add(fnFilter);

                              filters.add(lnFilter);

                              filters.add(emailFilter);

                              filters.add(nameFilter);

                            }

                            Filter combinedFilter = Filter.or(filters);

                            qo.addFilter(combinedFilter);

                          }

                          else {

                            //System.out.println("Creating displayName filter");

                            String concatParts = "";

                            for (String part : parts) {

                              //System.out.println("part = " + part);

                              concatParts += part;

                            }

                            concatParts = concatParts.replace(",", ", ");

                            //System.out.println("Searching dispalyName for: " + concatParts);

                            Filter displayName = Filter.ignoreCase(Filter.like("displayName", concatParts, Filter.MatchMode.START));

                            qo.addFilter(displayName);

                          }

                          List ordering = new ArrayList();

                          ordering.add(new QueryOptions.Ordering("lastname",  true));

                          ordering.add(new QueryOptions.Ordering("firstname", true));

                          qo.setOrderings(ordering);

                          return qo;

                        

                        </Source>

                    </Script>

                  </FilterScript>

                  <OrderBy>

                    <String>lastname</String>

                    <String>firstname</String>

                    <String>email</String>

                  </OrderBy>

                </IdentityFilter>

              </value>

            </entry>

Hi adam.hampton​,

Thanks for your comment. I think that your example is not related to my article, but to the other use case of the IdentitySelector class: Controlling Identity Suggests with IdentitySelectors​. My article is more about the UI-based configuration which is later used in one-by-one processing of identities like in e.g. policies, life cycle events, etc. Your example relates to the selectors where an end user can select an identity or sometimes a workgroup for forwarding, (re-)assignment, ownership, etc.: drop down lists. Apart from the differences in use, a major difference is that the IdentitySelector as used in my article do not need to search efficiently, but only to check for a match of a single identity, while the drop down lists should be responsive and return multiple identities quickly.

Regards,

Menno

Is there any documentation on "loggedInUser" and "loggedInUserWorkgroups"?  Specifically, regarding any other possible FilterParameters that could be used in an IdentitySelector filter?

For example, any parameter that could be passed to the identity selector filter when trying to forward a work item (i.e. limit the possible forward recipeint selection list based on the content of the work item selected)?

What can be passed into the Identity Selector is limited - you can not pass in additional variable.  Follow the link Menno provided to see a list of what is passed. You can dump the namespace. I provided the output I discovered when using those steps. There is no concrete documented list of the variables available.

For what you ask - the answer is no - you can not pass in additional variables. You can use the text typed into the suggest box (available as "parts" and "query") and use that to construct the filter. Other than that text, you just have the information tied to the logged in user.

Hi Menno,

is there any way to exclude those identity from mover certification, which are already exist in flight mover certification.

Ex: we have event based mover certification based on one identity attribute change we are launching certification, suppose identity attribute got changed for one user today, so it will launch certification and tomorrow again the identity attribute got changed..so it’s launching again the certification for same identity. can we prevent to launch certification for same user again as previous certification is already in flight.

If yes, do you have sample code for the same.

Thanks,

Gopal

I don't believe that that question is related to this article. Please, post your question as a new post on the forums and if you do not get an answer within a reasonable timeframe, share the question using the Share button.

@menno_pieters - Does a match list based identity selector support the use of an extended attribute on entitlements when configuring an advanced policy rule?

Basically, when I configure a match term for entitlement attributes in the UI, I only see values like owner, type, requestable, etc. when I clicked on the drop-down. However, let's say if I have an extended attribute called "Disabled" in the ManagedAttribute object, will it be possible to build a match expression using that attribute?

Thank you so much for you time.

@beam_ntth 

Under the hood, we can sometimes construct more complex expressions than you could in the UI. I would, however, not recommend to go down that route. It may break the next time you update the object that uses the identity selector from the UI. If you need a more powerful expression, use a rule or script.

- Menno

Version history
Revision #:
5 of 5
Last update:
‎Jul 03, 2023 12:11 PM
Updated by: