# Advanced Policy Violation Rule

**URL:** <https://developer.sailpoint.com/discuss/t/advanced-policy-violation-rule/69084>\
**Category:** IIQ Community Knowledge Base\
**Tags:** identityiq\
**Created:** [June 26, 2024, 2:28pm UTC](https://developer.sailpoint.com/discuss/t/advanced-policy-violation-rule/69084 "2024-06-26T14:28:41Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![KRM7](https://sea1.discourse-cdn.com/sailpoint/discuss/user_avatar/developer.sailpoint.com/krm7/32/2685_2.png) [@KRM7](https://developer.sailpoint.com/discuss/u/KRM7)\
**Post date:** [June 26, 2024, 2:28pm UTC](https://developer.sailpoint.com/discuss/t/advanced-policy-violation-rule/69084/1 "2024-06-26T14:28:42Z")

</div>

Hello Sailors,

If you would like to prevent user from submitting a Request for any business use cases

1. User should not have both approver and requestor Roles
2. User should not have more than 1 Role at a time
3. User who has account in application already can only request for the additional groups
4. Only some department users can request for the Role or Entitlement
5. Or any custom condition(s)

It is better to prevent the false request instead of depending on approvals, assuming that approver anyway will reject the request.

We have two types of policy violations

1. **Preventive** : Preventing user from having a specific access through LCM
2. **Detective** : Detecting violations for the access user already have

We will look into Preventive one here, we have couple of OOTB SoD Policy violation concepts.

1. **Role SoD** : You can use it if user should not have more than 1 Role at a time
2. **Entitlement SoD** : You can restrict entitlement requests based on some conditions

But the challenge with these are a lot of combinations you need to configure and not all the requirements can be implemented, that is where **Advanced Policy Violation** is useful.

As the name indicates, you can use it for complex customizations which are not feasible with OOTB.

You need a Rule for Advanced Policy implementation which is a bit tricky, let us go through the coding.

1. Import the libraries, import only you need and do not use \*

```auto
import sailpoint.object.Identity;
import sailpoint.object.Bundle;
import sailpoint.object.PolicyViolation;
import java.util.List;

```

1. Declare the Policy variables

```auto
PolicyViolation violation = null;
boolean vflag = false;
String desc = null;

```

1. You don’t get Plan as input, only identity you get in the Rule. This is optimistic Identity. What is that mean ?  
SailPoint considers that the requested access will be approved, so requested access is included in Identity.  
We should get Identity from DB which doesn’t have the requested access.

```auto
Identity reqIdentity = identity;
Identity dbIdentity = context.getObjectByName(Identity.class, identity.getName());

```

1. Now you have 2 identities, one with requested access and other one without the requested access. If you get access from both identities and compare/subtract then you get the requested access.

```auto
List dbIdRoles = dbIdentity.getAssignedRoles();
List reqIdRoles = reqIdentity.getAssignedRoles();

```

1. Optimistic (Requested) Identity will have both existing and requested Roles, so let’s subtract them to get just the requested ones

```auto
 if(reqIdRoles != null &amp;&amp; !reqIdRoles.isEmpty() &amp;&amp; dbIdRoles != null &amp;&amp; !dbIdRoles.isEmpty()) {
      reqIdRoles.removeAll(dbIdRoles);
    }

```

1. Add the conditions, if **reqIdRoles** size is more than 1 then set the violation flag as true and set the violation description which is presented to the requestor.

```auto
if (reqIdRoles.size() > 1 ) {
       vflag = true;
        desc = "You should not have more than 1 Role";
}

```

1. Set the violation object

```auto
if (vflag) {
    violation = new PolicyViolation();
    violation.setActive(true);
    violation.setIdentity(identity);
    violation.setPolicy(policy);
    violation.setConstraint(constraint);
    violation.setDescription(desc);
    violation.setStatus(sailpoint.object.PolicyViolation.Status.Open);
  }
  return violation;

```

Policy gets executed 2 times

1. Without considering the requested access, just to check if user is already in violation before placing the current request. If user is already in violation then no need to throw one more
2. By considering the requested access
3. So, you need write the condition #6 in such a way that violation is true in 2nd execution only. That is why I am subtracting the Roles. In 1st execution Roles list will be empty as both Identities will have same (existing) access.

You can implemented any kind of complex and customized Policy Violations using this feature. You do not need to purchase SAP GRC module, you can implement all of them inside SailPoint itself.

There will be a debate, why should we develop again when we can use already existing one. Well, I agree on that as well, if you are reqdy to pay for that cool, if not then make use of **Advanced Policy Violation**.

Hope this helps you 🙂

Thanks  
Krish

---

<div class="post-metadata">

**Author:** ![blazejbadzio](https://avatars.discourse-cdn.com/v4/letter/b/e9bcb4/32.png) [@blazejbadzio](https://developer.sailpoint.com/discuss/u/blazejbadzio)\
**Post date:** [July 29, 2024, 1:33pm UTC](https://developer.sailpoint.com/discuss/t/advanced-policy-violation-rule/69084/2 "2024-07-29T13:33:08Z")

</div>

Awesome instruction. Just a quick question, what if my policy after successfully executing, allows for “Submit with violation” ? Which arguments/attributes/options are responsible for allowing this action?

---

<div class="post-metadata">

**Author:** ![KRM7](https://sea1.discourse-cdn.com/sailpoint/discuss/user_avatar/developer.sailpoint.com/krm7/32/2685_2.png) [@KRM7](https://developer.sailpoint.com/discuss/u/KRM7)\
**Post date:** [July 29, 2024, 1:43pm UTC](https://developer.sailpoint.com/discuss/t/advanced-policy-violation-rule/69084/3 "2024-07-29T13:43:05Z")

</div>

![undefined](https://global.discourse-cdn.com/sailpoint/original/2X/8/8531b5a38b4ba9646288edebacd095be5d5372fc.png)

---

<div class="post-metadata">

**Author:** ![blazejbadzio](https://avatars.discourse-cdn.com/v4/letter/b/e9bcb4/32.png) [@blazejbadzio](https://developer.sailpoint.com/discuss/u/blazejbadzio)\
**Post date:** [July 29, 2024, 1:56pm UTC](https://developer.sailpoint.com/discuss/t/advanced-policy-violation-rule/69084/4 "2024-07-29T13:56:37Z")

</div>

But i want to forbid submitting the request on violation. And it can’t be that setting, since I have two policies (identical when it comes to type, and almost identical when it comes to returned value). But one is forbidding from submitting, and other is allowing for “submit with violation”. Any ideas why?

[Edit] Nevermind, i found it in custom piece of code regarding subprocess to LCM, by doing workflow.put(“allowRequestsWithViolations”, false).  
But thanks for trying 😉

---

<div class="post-metadata">

**Author:** ![ccastro1](https://avatars.discourse-cdn.com/v4/letter/c/5f9b8f/32.png) [@ccastro1](https://developer.sailpoint.com/discuss/u/ccastro1)\
**Post date:** [August 7, 2024, 4:06am UTC](https://developer.sailpoint.com/discuss/t/advanced-policy-violation-rule/69084/5 "2024-08-07T04:06:44Z")

</div>

Hi @KRM7  
Is there a way this rule can work both in Access Request (preventive) and Policy Scan (detective) ?

---

<div class="post-metadata">

**Author:** ![Arun-Kumar](https://sea1.discourse-cdn.com/sailpoint/discuss/user_avatar/developer.sailpoint.com/arun-kumar/32/15128_2.png) [@Arun-Kumar](https://developer.sailpoint.com/discuss/u/Arun-Kumar)\
**Post date:** [August 7, 2024, 7:32am UTC](https://developer.sailpoint.com/discuss/t/advanced-policy-violation-rule/69084/6 "2024-08-07T07:32:25Z")

</div>

Hi Christine,

when you implement an advanced policy using a Rule, it will work for both preventive and detective policy Evaluation.  
Evaluation during LCM access request is called a preventive way of finding violations as they finding violations in this stage may prevent assigning conflicting access rights.  
Evaluation during aggregation or identity cube refresh is a so called detective way of finding violations. There is an option to enable during the aggregation or identity refresh task for detective policy evaluation.

 ![image](https://global.discourse-cdn.com/sailpoint/original/2X/e/e4ed12a67582c26b2fc59df1c352051f5fd5fd4c.png)

Regards,  
Arun

---

<div class="post-metadata">

**Author:** ![ccastro1](https://avatars.discourse-cdn.com/v4/letter/c/5f9b8f/32.png) [@ccastro1](https://developer.sailpoint.com/discuss/u/ccastro1)\
**Post date:** [August 7, 2024, 8:07am UTC](https://developer.sailpoint.com/discuss/t/advanced-policy-violation-rule/69084/7 "2024-08-07T08:07:56Z")

</div>

Hi Arun, thanks for the reply. What I meant was from the sample shared by Krishna, it checks for both reqIdentity vs dbIdentity and subtracting the roles. For detective / identity refresh, is it the same case? Do we need to compare and subtract as well? As far as I know the identity being checked in detective is already the persistent identity from db.

---

<div class="post-metadata">

**Author:** ![a\_k1](https://avatars.discourse-cdn.com/v4/letter/a/c89c15/32.png) [@a\_k1](https://developer.sailpoint.com/discuss/u/a_k1)\
**Post date:** [January 22, 2025, 4:27pm UTC](https://developer.sailpoint.com/discuss/t/advanced-policy-violation-rule/69084/8 "2025-01-22T16:27:11Z")

</div>

Hi, is there anyway to get plan in advance policy violation?

---

<div class="post-metadata">

**Author:** ![a\_k1](https://avatars.discourse-cdn.com/v4/letter/a/c89c15/32.png) [@a\_k1](https://developer.sailpoint.com/discuss/u/a_k1)\
**Post date:** [January 22, 2025, 4:30pm UTC](https://developer.sailpoint.com/discuss/t/advanced-policy-violation-rule/69084/9 "2025-01-22T16:30:32Z")

</div>

In refresh, it checks only dbidentity

---

<div class="post-metadata">

**Author:** ![jonasmansson](https://avatars.discourse-cdn.com/v4/letter/j/fbc32d/32.png) [@jonasmansson](https://developer.sailpoint.com/discuss/u/jonasmansson)\
**Post date:** [January 27, 2025, 2:27pm UTC](https://developer.sailpoint.com/discuss/t/advanced-policy-violation-rule/69084/10 "2025-01-27T14:27:56Z")

</div>

Hi Arun, excellent example and guide!

However I am not able to get this to work in the standard LCM provisioning business process. I tried both 8.3 and 8.4.

I have created an Advance Policy which always returns a policy violation (always : vflag = true) as per your code. I have added logout as well to be able to trace that the rule is doing what it is supposed to.

 ![image](https://global.discourse-cdn.com/sailpoint/original/3X/e/e/ee43dd50a6390a90620bf654a386dd11210d9523.png)

In LCM Provisioning I have the “Fail workflow” and selected the policy I created.

After the submit of a access request I can see the log-outs (rule is called twice) just as you mentioned, the vioalation is created, but the workflow continues as normal. No policy violation is created and no one can be seen in debug pages…

Any obvious reason why it does not work as expected?

Thanks,

Jonas

---

<div class="post-metadata">

**Author:** ![kvyas1](https://avatars.discourse-cdn.com/v4/letter/k/7ab992/32.png) [@kvyas1](https://developer.sailpoint.com/discuss/u/kvyas1)\
**Post date:** [March 7, 2025, 8:32pm UTC](https://developer.sailpoint.com/discuss/t/advanced-policy-violation-rule/69084/11 "2025-03-07T20:32:04Z")

</div>

> [@KRM7](#):
>
> `t.PolicyViolation.Status.Op`

Hi @KRM7  
I am able to catch the violation, but along with violation, it still shows the option for approve and deny and even let you approve the assignment. How can I either fail the workflow along with violation or at least disable the approve button?

Thanks in advance,  
Kapil.

---

<div class="post-metadata">

**Author:** ![KRM7](https://sea1.discourse-cdn.com/sailpoint/discuss/user_avatar/developer.sailpoint.com/krm7/32/2685_2.png) [@KRM7](https://developer.sailpoint.com/discuss/u/KRM7)\
**Post date:** [March 7, 2025, 8:44pm UTC](https://developer.sailpoint.com/discuss/t/advanced-policy-violation-rule/69084/12 "2025-03-07T20:44:20Z")

</div>

Check your LCM workflow, policy settings, you might have selected continue on Policy violations. You should select Present Failures to Requesters.

 ![image](https://global.discourse-cdn.com/sailpoint/original/3X/9/0/90873745859b0c2a33dadb2be85b8e6c89e2329f.png)

---

<div class="post-metadata">

**Author:** ![kvyas1](https://avatars.discourse-cdn.com/v4/letter/k/7ab992/32.png) [@kvyas1](https://developer.sailpoint.com/discuss/u/kvyas1)\
**Post date:** [March 7, 2025, 9:45pm UTC](https://developer.sailpoint.com/discuss/t/advanced-policy-violation-rule/69084/13 "2025-03-07T21:45:11Z")

</div>

Thanks @MVKR7T but I do not want to do that as it will be applicable to all policies. Is there any way to do it programmatically ? I am using a “policy” rule which is returning violation and then control goes to “violation formatting rule”. Is there anyway I can cancel the workflow here? I see [this post](https://community.sailpoint.com/t5/IdentityIQ-Forum/How-To-Stop-Policy-Violation-Access-Request-Submission/m-p/185759#M147378) talks about 'allowRequestsWithViolations ’ variable but not sure how to set it ?

---

<div class="post-metadata">

**Author:** ![bgibson](https://avatars.discourse-cdn.com/v4/letter/b/9fc348/32.png) [@bgibson](https://developer.sailpoint.com/discuss/u/bgibson)\
**Post date:** [June 26, 2025, 2:30pm UTC](https://developer.sailpoint.com/discuss/t/advanced-policy-violation-rule/69084/14 "2025-06-26T14:30:32Z")

</div>

Hi @KRM7,

I am trying to do something extremely similar to this post but with entitlements. You mentioned that this is possible. However, I seem to have trouble getting the difference between the DB identity’s entitlements and optimistic identities entitlements.

Your post goes through roles, which works great, however I can’t seem to replicate it with entitlements. There is no `getAssignedAttributes()` call or something along those lines like with roles, so I am attempting to do so `getAttributeAssignments()`. The issue is that this does not seem to detect any difference between the two identities.

How can I do essentially your original post, but with entitlements/managed attributes if getting the attribute assignments does not work?

This is my current test policy rule that works great when changing to use roles with `getAssignedRoles`, but not with checking entitlements:

```auto
  Identity dbIdentity = context.getObjectByName(Identity.class, identity.getName());
  List assignments = identity.getAttributeAssignments();
  List old = dbIdentity.getAttributeAssignments();

  if (assignments != null &amp;&amp; !assignments.isEmpty() &amp;&amp; old != null &amp;&amp; !old.isEmpty()) {
  	assignments.removeAll(old);
  }
  // Check for Violation
  if (assignments != null &amp;&amp; !assignments.isEmpty()) {
    polVil = new PolicyViolation();
    polVil.setActive(true);
    polVil.setIdentity(identity);
    polVil.setPolicy(policy);
    polVil.setDescription(assignments.toString());
  }

```

---

<div class="post-metadata">

**Author:** ![KRM7](https://sea1.discourse-cdn.com/sailpoint/discuss/user_avatar/developer.sailpoint.com/krm7/32/2685_2.png) [@KRM7](https://developer.sailpoint.com/discuss/u/KRM7)\
**Post date:** [June 26, 2025, 2:34pm UTC](https://developer.sailpoint.com/discuss/t/advanced-policy-violation-rule/69084/15 "2025-06-26T14:34:41Z")

</div>

From both Identities, get the respective Link object and compare them to get the requested entitlements.

---

<div class="post-metadata">

**Author:** ![kkanathe](https://avatars.discourse-cdn.com/v4/letter/k/ecae2f/32.png) [@kkanathe](https://developer.sailpoint.com/discuss/u/kkanathe)\
**Post date:** [August 7, 2025, 3:03pm UTC](https://developer.sailpoint.com/discuss/t/advanced-policy-violation-rule/69084/16 "2025-08-07T15:03:39Z")

</div>

Hi @krishna4017 - Even I’m trying to do something similar with entitlements, but the issue is, that identity object available in the rule is not the optimistic one as you mentioned above. It is just returning the current identity object

---

<div class="post-metadata">

**Author:** ![KRM7](https://sea1.discourse-cdn.com/sailpoint/discuss/user_avatar/developer.sailpoint.com/krm7/32/2685_2.png) [@KRM7](https://developer.sailpoint.com/discuss/u/KRM7)\
**Post date:** [August 7, 2025, 3:23pm UTC](https://developer.sailpoint.com/discuss/t/advanced-policy-violation-rule/69084/17 "2025-08-07T15:23:11Z")

</div>

for entitlements, get link object of both identities and compare.

---

<div class="post-metadata">

**Author:** ![NKumar97](https://avatars.discourse-cdn.com/v4/letter/n/a183cd/32.png) [@NKumar97](https://developer.sailpoint.com/discuss/u/NKumar97)\
**Post date:** [October 3, 2025, 11:48am UTC](https://developer.sailpoint.com/discuss/t/advanced-policy-violation-rule/69084/18 "2025-10-03T11:48:19Z")

</div>

If i use the advance policy, then i don’t see the policy violation owner is getting assigned even through UI.

---

<div class="post-metadata">

**Author:** ![fhlbp0k](https://avatars.discourse-cdn.com/v4/letter/f/278dde/32.png) [@fhlbp0k](https://developer.sailpoint.com/discuss/u/fhlbp0k)\
**Post date:** [November 10, 2025, 6:01pm UTC](https://developer.sailpoint.com/discuss/t/advanced-policy-violation-rule/69084/19 "2025-11-10T18:01:21Z")

</div>

Hi @KRM7,

Thank you for the post on **[Advanced Policy Violation Rule](https://developer.sailpoint.com/discuss/t/advanced-policy-violation-rule/69084).**

I’m trying do similar, but I want to restrict identity to have only one Role for specific application.

Issue I’m getting:

When there is “Classifications” value assigned under the Role. In “reqIdRoles” the Role I’m requesting is not detected. Please assist.

 ![image](https://global.discourse-cdn.com/sailpoint/original/3X/e/8/e88d1ebc1e8954b42455c251c3cafb2618653acf.png)

Thank you

```java
import sailpoint.object.Identity;
import sailpoint.object.Bundle;
import sailpoint.object.PolicyViolation;
import java.util.List;

PolicyViolation violation = null;
boolean vflag = false;
String desc = null;

Identity reqIdentity = identity;
Identity dbIdentity = context.getObjectByName(Identity.class, identity.getName());

List reqIdRoles = reqIdentity.getAssignedRoles();

// testing code
int count = 0;
for(Bundle bun : reqIdRoles){
Attributes attrsBun = bun.getAttributes();
if(attrsBun.contains(“applicationName”)){
if(“Fin”.equalsIgnoreCase(attrsBun.get(“applicationName”))){
count = count +1;
}
}
}
if (count > 1 ) {
vflag = true;
desc = “Can not have more than 1 Role”;
}
if (vflag) {
violation = new PolicyViolation();
violation.setActive(true);
violation.setIdentity(identity);
violation.setPolicy(policy);
violation.setConstraint(constraint);
violation.setDescription(desc);
violation.setStatus(sailpoint.object.PolicyViolation.Status.Open);
}
return violation; 

```

---

<div class="post-metadata">

**Author:** ![KRM7](https://sea1.discourse-cdn.com/sailpoint/discuss/user_avatar/developer.sailpoint.com/krm7/32/2685_2.png) [@KRM7](https://developer.sailpoint.com/discuss/u/KRM7)\
**Post date:** [November 10, 2025, 8:18pm UTC](https://developer.sailpoint.com/discuss/t/advanced-policy-violation-rule/69084/20 "2025-11-10T20:18:29Z")

</div>

Refer to my post, points 4, 5, 6. You need to subtract the Roles.

[Next page](https://developer.sailpoint.com/discuss/t/advanced-policy-violation-rule/69084.md?page=2)
