This article explains how to implement a detective type of Advanced Policy in SailPoint IIQ using Filters and Rules with a sample business scenario.
IdentityIQ Versions: 7.0, 7.1 and above
SailPoint IIQ provides several features for addressing the compliance requirements of organizations. SoD (Segregation of Duty) Policy and Certification are some of the options. SoD policy basically consists of verifying an Identity against a set of Policy rules and creating a policy violation if any conflicts are found in access permissions, roles or entitlements etc.., based on the compliance regulations set by the organizations. Policy violation can be acted upon by a designated owner who can take a corrective action by removing the access through certification or taking an exception to violation with a proper explanation.
NOTE: Scope of this article is limited to develop a detective type of Advanced SoD Policy consisting of rules with options like Filters and custom Rules. SoD Policies is a bigger topic in itself and comes up with various types of policies like Entitlement Policy, Role Policy, Activity Policy and its related configurations. Reference is provided in suggested readings section with several links for articles and product documentation to explore more on this topic.
In today’s world, organizations are required to meet the challenge of compliance at every level. In the Identity and Access Management domain there will be restrictions on access level, roles and permissions identities need to have based on the organization’s compliance needs. Below table lists two compliance requirement scenarios which are most likely to occur in any organization, these two requirements can be formulated as Policy Rules inside an advanced policy and violations can be raised to handle the compliance regulations.
Sl. No. |
Application |
Entitlement/Role |
Business Rule |
1. |
Test App |
TEST_ENT_1 |
Access only to Identities with: Business Unit - Finance Department – “Payroll” OR “Invoice Processing” Job Title – Accountant |
2. |
Test App |
TEST_ENT_2 |
Access only to Identities with: Role – Security Officer |
NOTE: Sample XML files provided in this article can be used as a reference and modified as the per environment needs.
This sections explains the implementation details in IIQ, below Figure 1, shows the Advanced Policy creation page with controls to create policy rules. Figure 2, shows the Policy Rules creation page with Selection Method options, “Match List”, “Filter”, “Script”, “Rule” and “Population” are the available choices. These are basically Identity Selector configurations, this article focuses on “Filter” and “Rule” options for implementing the above two business requirements respectively.
NOTE: Decision to implement the business requirements using Advanced SoD Policy is mainly due to the complexity level and the conditions/comparisons which needs to be evaluated for an identity. Other types of policies doesn’t provide much flexibility for customization. For more information on this, refer to suggested readings section.
Figure 1: Advanced Policy Creation page with UI controls to create Policy Rules
Figure 2: Policy Rules creation page with Selection Method’s for Advanced Policy
IIQ provides Filter selection method for querying the identities in an XML format. For the first sample requirement mentioned above, xml filter query can be written as shown below. This will use a combination of “Composite Filters” with AND, OR and NOT operators, “Filters” with EQ & NE operators for selecting the identities and raising policy violations.
Figure 3: Shows an Identity Selector configuration using filters, this will detect for identities with entitlement “TEST_ENT_1” in “Test App” application. If the identity doesn’t belong to particular Business Unit or Department or Job Title apart from the preferred ones then a Policy Violation will be raised to correct the access issue (Using AND, OR, EQ, NE and NOT operators is for evaluating these conditions should be noted carefully, indexing for attributes Business Unit, Department and Job Title are not used for search as they are identity attributes)
<CompoundFilter>
<Applications>
<Reference class="sailpoint.object.Application" name="Test App"/>
</Applications>
<CompositeFilter operation="AND">
<CompositeFilter operation="AND">
<Filter operation="EQ" property="0:Entitlements" value="TEST_ENT_1"/>
</CompositeFilter>
<CompositeFilter operation="OR">
<Filter operation="NE" property="businessUnit" value="Finance"/>
<CompositeFilter operation="NOT">
<Filter operation="IN" property="departmentName">
<Value>
<List>
<String>Payroll</String>
<String>Invoice Processing</String>
</List>
</Value>
</Filter>
</CompositeFilter>
<Filter operation="NE" property="jobTitle" value="Accountant"/>
</CompositeFilter>
</CompositeFilter>
</CompoundFilter>
Figure 3: Sample xml filter which detects an identity based on the filter conditions
IIQ provides Rule based selection method for querying the identities written using Java Beanshell code. For the second requirement mentioned above, custom rule can be written as shown below.
Figure 4: Shows an Identity Selector using a custom rule which uses API provided by the SailPoint framework to query the identities, this code will check for identities with an entitlement “TEST_ENT_2” in “Test App” application. Also, it will check for the assigned role “Security Officer” on an identity and raises Policy Violation if it is not assigned (Usage of Java Beanshell API for evaluating the identities should be noted carefully)
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Rule language="beanshell" name="Test SOD Policy Rule" type="Policy">
<Description>This rule is to determine if a Policy has been violated.</Description>
<Signature returnType="PolicyViolation">
<Inputs>
<Argument name="log"/>
<Argument name="context"/>
<Argument name="identity"/>
<Argument name="policy"/>
<Argument name="constraint"/>
</Inputs>
<Returns>
<Argument name="violation">
<Description>The PolicyViolation object.</Description>
</Argument>
</Returns>
</Signature>
<Source>
<![CDATA[
import sailpoint.object.*;
import java.util.*;
import java.text.*;
import org.apache.log4j.Logger;
import org.apache.log4j.Level;
Logger log = Logger.getLogger("identity.test.sodPolicy");
log.debug("=== ENTER: Test SOD Policy ===");
PolicyViolation polVil = null;
boolean isViolation = false;
if (identity != null) {
String identityidentityName = identity.getName();
log.debug(" Test SOD : identityName ---"+identityName);
List roleAssigns = identity.getAssignedRoles();
log.debug("Have roleAssigns: " + roleAssigns);
boolean roleViolation = true;
if (roleAssigns != null){
log.debug("# currently assigned = " + roleAssigns.size());
for (Bundle roleAssign : roleAssigns){
String rName = roleAssign.getName();
log.debug("Have role assign: " + rName);
if(rName.equalsIgnoreCase("Security Officer")){
roleViolation = false;
}
}
}
List links = identity.getLinks();
if(links != null && links.size() > 0){
log.debug(" Test SOD : Inside links ---");
//==Declare variables
String appName;
List entitlements;
String entVal;
//==Iterate thru the links
for (Link link : links) {
if (link != null && !link.isDisabled()) {
appName = link.getApplicationName();
log.debug(" Test SOD : appName ---"+appName);
if (appName != null && appName.equalsIgnoreCase("Test App")) {
log.debug(" Test SOD : Inside Test App ---");
//==Retrieve the entitlements for the Application
entitlements = link.getEntitlements(Locale.getDefault(),"");
if(entitlements != null && entitlements.size() > 0){
log.debug(" Test SOD : Inside Entitlements ---");
//==Iterate thru the entitlements
for(Entitlement entitlement : entitlements){
entVal = entitlement.getAttributeValue();
log.debug(" Test SOD : entVal ---"+entVal);
if(entVal.equalsIgnoreCase("TEST_ENT_2")){
log.debug(" Test SOD : entVal : TEST_ENT_2---");
if(roleViolation){
//==Set the Policy Violation flag if Role Violation is Present
isViolation = true;
}
}
}
}
}
}
}
}
}
//==Check for Violation
if (isViolation) {
log.debug(" Test SOD : Inside Violation ---");
polVil = new PolicyViolation();
polVil.setActive(true);
polVil.setIdentity(identity);
polVil.setPolicy(policy);
polVil.setDescription("This combination of Role is not allowed for the Identity");
}
log.debug("=== EXIT: Test SOD Policy ===");
return polVil;
]]>
</Source>
</Rule>
Figure 4: Sample IIQ Rule file to detect Identities and raise policy violation for conflicting roles
After adding Rules to Advanced Policy
After adding the above policy rules to an advanced policy, Figures 5 and 6 below will show the details of how the policy looks in IIQ UI and xml file representation of the advanced policy for the sample business scenario.
Figure 5: shows advanced policy with “Test Rule 1” and “Test Rule 2” which are Filter and Rule features.
Figure 5: Advanced policy with policy rules created as Filter and Custom Rule
Figure 6: shows the xml representation of the Test Advanced policy configuration for business scenario.
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Policy PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Policy certificationActions="Mitigated,Delegated" configPage="advancedPolicy.xhtml" executor="sailpoint.policy.GenericPolicyExecutor"
name="Test Advanced SoD Policy" state="Inactive" type="Advanced" typeKey="policy_type_advanced" violationOwnerType="Identity">
<PolicyAlert disabled="true" escalationStyle="none"/>
<Attributes>
<Map>
<entry key="sysDescriptions">
<value>
<Map>
<entry key="en_US" value="Test Advanced SoD Policy"/>
</Map>
</value>
</entry>
</Map>
</Attributes>
<Owner>
<Reference class="sailpoint.object.Identity" name="spadmin"/>
</Owner>
<ViolationOwner>
<Reference class="sailpoint.object.Identity" name="spadmin"/>
</ViolationOwner>
<GenericConstraints>
<GenericConstraint name="Test Rule 1" violationOwnerType="None">
<CompensatingControl>Test Rule 1</CompensatingControl>
<Description>Test Rule 1</Description>
<RemediationAdvice>Test Rule 1</RemediationAdvice>
<IdentitySelector>
<CompoundFilter>
<CompositeFilter operation="AND">
<CompositeFilter operation="AND">
<Filter operation="EQ" property="0:Entitlements" value="TEST_ENT_1"/>
</CompositeFilter>
<CompositeFilter operation="OR">
<Filter operation="NE" property="businessUnit" value="Finance"/>
<CompositeFilter operation="NOT">
<Filter operation="IN" property="departmentName">
<Value>
<List>
<String>Payroll</String>
<String>Invoice Processing</String>
</List>
</Value>
</Filter>
</CompositeFilter>
<Filter operation="NE" property="jobTitle" value="Accountant"/>
</CompositeFilter>
</CompositeFilter>
</CompoundFilter>
</IdentitySelector>
</GenericConstraint>
<GenericConstraint name="Test Rule 2" violationOwnerType="None">
<CompensatingControl>Test Rule 2</CompensatingControl>
<Description>Test Rule 2</Description>
<RemediationAdvice>Test Rule 2</RemediationAdvice>
<IdentitySelector>
<RuleRef>
<Reference class="sailpoint.object.Rule" name="Test SOD Policy Rule"/>
</RuleRef>
</IdentitySelector>
</GenericConstraint>
</GenericConstraints>
</Policy>
Figure 6: Sample advanced policy xml file with Filter and Rule configurations
Testing can be executed for SoD Policies in several ways, through "Aggregation", "Identity Refresh" and "Policy Scan" types of tasks are very common. “Simulation” feature available for policy rule and in the SoD Policy is another option for unit testing. Verifying the identity against policy using “Policy Scan” task is explained below.
NOTE: For more information on Testing refer to links provided in suggested readings section.
Figure 7: shows the snapshot of a “Policy Scan” type of Task, which can verify the identity against the policy. As shown in the figure, task contains the details of the identity which needs to be verified and the name of the policy which needs to be evaluated, when executed task will evaluate all the policy rules and raises the policy violation. Policy owner can take appropriate action on the violation.
Figure 7: Policy scan task to test the identity against the advanced policy
Figure 8: shows the snapshot of a “Policy Violations” raised after the task has run. Policy owner can take several actions like allowing the violation as an exception till the desired date so that there will not be any violation raised till the expiry date. Also, other option is to do a certification and re-mediate the conflicting access.
Figure 8: Sample xml filter which detects an identity based on the filter conditions
NOTE: During testing, for better tracking of the flow, log statements can be enabled with proper permission and trace levels. Some log statements are provided inside the sample files can be utilized for tracing or debugging purposes.
Document Revision History
Revision Date |
Written/Edited By |
Comments |
Jun 2018 |
Jayaram K H |
Initial Creation For IIQ versions: 7.0, 7.1 and above |
Hello Jayaram,
I created an advanced policy with rule defined. When i ran Policy Scan task, i can see the policy violations.
But somehow, in access request, the policy violation can't be seen in the approval request (In LCM Provisioning workflow, the policy setting is "Continue On Policy Violations".
I traced the workflow, seems in "policyViolations" call, this advanced policy is evaluated. I can see the policy violation is created in the rule log. But the "policyViolations" function returns null so it is not in Approval request.
Any ideas? Is there any config i need to set?
Many thanks!
Bill
When creating advanced policy, I am using a match list instead of a rule, I need to select an application and flag a violation if user has access to any of the attributes within that app. Looks like I cannot add multiple values of the attribute separated by a comma.
Is this is a limitation or am I doing something wrong?
@bill_qian - use "interactive" in your LCM config.
<Variable initializer="interactive" input="true" name="policyScheme">
<Description>A String that specifies how policy checks effect the overall
process.
none - disabled policy checking
continue - continue if policy violations are found
interactive - allow requester to remove request items which are causing violations
fail - this option will cause the workflow to terminate immediately if any policy violations are found.
Note that the requester will not be notified that the workflow has terminated.</Description>
</Variable>
@dk0200 - probably you need "IN" filter.
<CompositeFilter operation="NOT">
<Filter operation="IN" property="departmentName">
<Value>
<List>
<String>Payroll</String>
<String>Invoice Processing</String>
</List>
</Value>
</Filter>
</CompositeFilter>
@dk0200 In match list option you can't add multiple values in comma separated format. To achieve this you need to add same attribute in the list and then add next value whatsoever it is.
i am facing the same issue , in advanced policy rule , the policy violation objected is returned but in request workflow the policyViolations is returned as null , eventhough poilcy scheme is interactive
Hi,
Cant we test advanced policy using Access Request ? Because article mentioned only through "Aggregation", "Identity Refresh" and "Policy Scan" . We have a requirement to prevent several role request if user doesn't have pre-requisite role .
Thank you,
Jayaram T
@sbalarethenam Were you able to find a solution for your issue? we are also facing same issue where even though we return policy violation in the rule, in the Request access workflow its returned null.
Please suggest
Through Advanced Policy can we also validate if there are any conflicting access request which are in pending approval state?
Currently I see the Policy rule does not check any Approvals which are in pending state.
Please suggest any solution