Advanced Entitlement Policy Rule

Hi @JuneTaylor,

You can refer to below given link that can be helpful while implementing advance SOD via workflow. Also, I have attached sample workflow that is shipped with SailPoint as an example.

Sample Workflow :

<Workflow name='Policy Violation'
          type='PolicyViolation'
          handler='sailpoint.api.StandardWorkflowHandler'>

  <Variable name='approvalObject' input='true'>
    <Description>
      PolicyViolation to process.  Note that we use approvalObject for
      consistency with other workflows, but the violation has already
      been persisted.  Calling the commit or rollback actions will 
      have no effect.
    </Description>
  </Variable>

  <Variable name='approver' input='true'>
    <Description>
      The user to receive the work item, normally the owner of 
      the policy.
    </Description>
  </Variable>

  <Variable name='violator' input='true'>
    <Description>
      The identity that has the violation.
    </Description>
  </Variable>

  <Variable name='approved'>
    <Description>
      Internal variable automatically set logically true an Approval
      process completes with no rejects.
    </Description>
  </Variable>

  <Variable name='action'>
    <Description>
      Variable that may be set in the approval page to determine 
      the action to take on this violation.  We handle violation approvals
      differently than most work items.  There is no "reject" there
      is a selection of an action (mitigate, remediate, delete, ignroe) 
      followed by buttons that always post approval.
    </Description>
  </Variable>

  <Variable name='expiration'>
    <Description>
      Variable that must be set to a Date (or the String representation
      of a Date) in order to use the "mitigate" action.  This will
      be tested in the call:mitigate handler and logged if it is invalid.
      You may wish to have the worklfow do it's own validation.
    </Description>
  </Variable>

  <Variable name='comments'>
    <Description>
      Variable that may be set to comments to be included with
      a mitigation or remediation.
    </Description>
  </Variable>

  <Variable name='remediatables' initializer='call:getRemediatables'>
    <Description>
      Variable that may be set to a list of things that can
      be selected for remediation.  Currently this will only
      be set for Role SOD violations.
    </Description>
  </Variable>

  <Variable name='remediations'>
    <Description>
      Variable holding the remediatables selected in the work item.
    </Description>
  </Variable>

  <Step name='Start'>
    <Transition to='No Approver' 
      when='approver == unbound || approver == null'/>
  </Step>

  <Step name='Approve'>
    <Description>
      The example page posts action values taken from the
      names of the CertificationAction.Status enumeration
      (Approved, Mitigated, Remediated, Acknowledged) plus
      a few custom ones (Ignored, Deleted).
    </Description>
    <Approval owner='ref:approver' renderer='policyViolation.xhtml' 
      send='launcher,approvalObject,remediatables' return='action,expiration,remediations,comments'>
      <Arg name='workItemDescription' 
        value='Review violation of policy $(script:approvalObject.getPolicyName();) on $(violator)'/>
		      <Arg name="workItemType" value="PolicyViolation"/>
      <ValidatorScript>
        <Source>
            String error = null;
            String action = (String)item.getAttribute("action");
            if ("Mitigated".equals(action)) {
                // make sure they've selected a date
                Date expiration = item.getDate("expiration");
                if (expiration == null) {
                    // TODO: should make sure it's a valid date too
                    error = "Please enter an expiration date";
                }
            }
            else if ("Remediated".equals(action)) {
                // make sure they've selected some remediatables
                List remediations = item.getList("remediations");
                if (remediatables != null &amp;&amp; 
                    remediatables.size() > 0 &amp;&amp;
                    (remediations == null || remediations.size() == 0)) {
                    error = "Please select items to remediate";
                }
            }
            else if (action == null || action.trim().length() == 0 ||
                     "none".equals(action)) {
                error = "Please select an action.";
            }
            return error;
        </Source>
      </ValidatorScript>
    </Approval>
    <Transition to='Mitigate' when='"Mitigated".equals(action)'/>
    <Transition to='Remediate' when='"Remediated".equals(action)'/>
    <Transition to='Delete' when='"Deleted".equals(action)'/>
    <!-- should be Acknowledged -->
    <Transition to='Ignore'/>
  </Step>

  <Step name='Mitigate' action='call:mitigateViolation'>
    <Description>
      Setup a mitigation expiration and other certification artifacts
      that make it look like the violation was mitigated through
      the normal cert process or the violation management pages.
    </Description>
    <Transition to='End'/>
  </Step>

  <Step name='Remediate' action='call:remediateViolation'>
    <Description>
      Setup a remediation and other certification artifacts
      that make it look like the violation was mitigated through
      the normal cert process or the violation management pages.
    </Description>
    <Arg name='remediations' value='ref:remediations'/>
    <Transition to='End'/>
  </Step>

  <Step name='Delete' action='call:delete'>
    <Description>
      Delete the violation so it doesn't continue to show up in the UI.
    </Description>
    <Transition to='End'/>
  </Step>

  <Step name='Ignore' action='call:ignore'>
    <Description>
      Leave the violation in place.
    </Description>
    <Transition to='End'/>
  </Step>

  <Step name='No Approver' action='call:print'>
    <Arg name='message' value='No approver for policy $(script:approvalObject.policyName)'/>
  </Step>

  <Step name='End'/>

</Workflow>

Thanks