# Segregation of duties

**Segregation of Duties** (SoD) is a security and compliance control that prevents any single user from holding a combination of access rights that could enable fraud, error, or abuse of privilege. In OpenIAM, SoD policies define which entitlements (roles, groups, resources, or organizations) are considered conflicting, detect users who violate those policies, and provide tooling to remediate or formally exempt violations.

The SoD feature is typically used for:

* Preventing a user from holding **both** "Create Payment" and "Approve Payment" roles **simultaneously**.
* Flagging users who belong to **conflicting business units**.
* Ensuring compliance with **SOX**, **SOC 2**, **ISO 27001**, or **internal audit** requirements.

***

## Core concepts

### SoD policy

A **SoD Policy** is the top-level object defining a conflict with the following key attributes:

<table><thead><tr><th width="207">Field</th><th width="244.66668701171875">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>name</code></td><td>String</td><td>Human-readable policy name</td></tr><tr><td><code>description</code></td><td>String (max 1024 characters)</td><td>Explanation of the conflict</td></tr><tr><td><code>active</code></td><td>Boolean</td><td>Whether the policy is enforced</td></tr><tr><td><code>severity</code></td><td><code>SOFT</code> / <code>HARD</code></td><td>Impact level of a violation (see <a href="/pages/6b6z7brL759BotIQKvT1#severity-levels"><strong>Severity levels</strong></a>)</td></tr><tr><td><code>policyThreshold</code></td><td>Integer</td><td>Minimum number of violated segments before a policy-level violation is triggered</td></tr><tr><td><code>exceptionsAllowed</code></td><td>Boolean</td><td>Whether exemptions may be granted for this policy</td></tr><tr><td><code>managerCanHandleSpv</code></td><td>Boolean</td><td>Whether the user's manager may handle violations</td></tr><tr><td><code>managerGroupId</code></td><td>String</td><td>ID of the group responsible for managing violations</td></tr><tr><td><code>riskId</code> / <code>riskName</code></td><td>String</td><td>Risk classification category</td></tr><tr><td><code>segments</code></td><td><code>Set&#x3C;SodPolicySegment></code></td><td>One or more conflict segments (see <a href="#policy-segments"><strong>policy segments</strong></a>)</td></tr><tr><td><code>mitigatingControls</code></td><td><code>Set&#x3C;SodMitigatingControl></code></td><td>Controls that mitigate the policy risk (see <a href="#mitigating-controls"><strong>mitigating controls</strong></a>)</td></tr></tbody></table>

### Policy segments

A **segment** defines the specific set of conflicting entitlements within a policy. A policy can have multiple segments. The `policyThreshold` controls how many segments must be violated before the policy is considered violated overall, whereas `threshold` controls the minimum number of entitlements from that segment a user must hold to contribute to a violation.

Each segment contains:

<table><thead><tr><th width="207.3333740234375">Field</th><th>Description</th></tr></thead><tbody><tr><td><code>name</code> / <code>description</code></td><td>Segment identification</td></tr><tr><td><code>active</code></td><td>Whether this segment is actively evaluated</td></tr><tr><td><code>threshold</code></td><td>Minimum conflicting entitlements within the segment to trigger violation</td></tr><tr><td><code>managerGroupId</code></td><td>Segment-level manager group (overrides policy-level if set)</td></tr><tr><td><code>roles</code></td><td>Roles that are in conflict within this segment</td></tr><tr><td><code>groups</code></td><td>Groups that are in conflict within this segment</td></tr><tr><td><code>resources</code></td><td>Resources that are in conflict within this segment</td></tr><tr><td><code>organizations</code></td><td>Organizations that are in conflict within this segment</td></tr></tbody></table>

**For example**: A segment named "Payment Controls" might contain both the "Payment Creator" role and the "Payment Approver" role. Any user holding both would trigger a violation of this segment.

### Typical two-segment policy

```
Policy: "Create + Approve PO"   Threshold: 2 segments
│
├── Segment A: "Create PO"      Threshold: 1 entitlement
│   ├── Role: PO_CREATOR
│   └── Resource: create-purchase-order
│
└── Segment B: "Approve PO"     Threshold: 1 entitlement
    ├── Role: PO_APPROVER
    └── Resource: approve-purchase-order

A user holding PO_CREATOR AND PO_APPROVER breaches both segments → violation.
A user holding only PO_CREATOR does not violate (only 1 of 2 segments breached).
```

### Mitigating controls

A **mitigating control** is a compensating measure that reduces the risk of an SoD violation without removing the conflicting access. Mitigating controls are documented in the system for audit purposes and linked to policies.

<table><thead><tr><th width="290">Field</th><th>Description</th></tr></thead><tbody><tr><td><code>name</code> / <code>description</code></td><td>Control identification</td></tr><tr><td><code>active</code></td><td>Whether the control is active</td></tr><tr><td><code>ownerType</code> / <code>ownerId</code></td><td>User or group that owns the control</td></tr><tr><td><code>managerType</code> / <code>managerId</code></td><td>User or group that manages the control</td></tr><tr><td><code>reviewFrequency</code></td><td><code>MONTHLY</code>, <code>QUARTERLY</code>, <code>SEMI_ANNUALLY</code>, or <code>ANNUALLY</code></td></tr><tr><td><code>effectiveDate</code> / <code>expirationDate</code></td><td>Validity period of the control</td></tr></tbody></table>

## Data model summary

```
SodPolicy (SOD_POLICY)
  ├── segments: SodPolicySegment (SOD_POLICY_SEGMENT) [1..N]
  │     ├── roles      → SOD_SEGMENT_ROLE    → RoleEntity
  │     ├── groups     → SOD_SEGMENT_GRP     → GroupEntity
  │     ├── resources  → SOD_SEGMENT_RES     → ResourceEntity
  │     └── organizations → SOD_SEGMENT_ORG  → OrganizationEntity
  └── mitigatingControls → SOD_POLICY_MC → SodMitigatingControl (SOD_MITIGATING_CONTROL)

SodExemption
  └── references: user, sodPolicy, entitlementType, entitlementId
```

Boolean flags (`active`, `exceptionsAllowed`, `managerCanHandleSpv`) are stored as `Y`/`N` in the database via `YesNoConverter`.

## Caching architecture

All SoD policies are cached in **Redis** (`SodPolicyCacheList`) for fast access during entitlement evaluations. The cache is refreshed automatically whenever a policy is created or updated. Cache refresh is propagated via **RabbitMQ** (`SodPolicyMQListener`) to all service nodes.

## Enumerations reference

<table><thead><tr><th width="337.33331298828125">Enum</th><th>Values</th></tr></thead><tbody><tr><td><code>SodSeverity</code></td><td><code>SOFT</code>, <code>HARD</code></td></tr><tr><td><code>SodViolationMode</code></td><td><code>DIRECT</code>, <code>INDIRECT</code></td></tr><tr><td><code>SodMitigatingControlAssigneeType</code></td><td><code>USER</code>, <code>GROUP</code></td></tr><tr><td><code>SodMitigatingControlReviewFrequency</code></td><td><code>ANNUALLY</code>, <code>SEMI_ANNUALLY</code>, <code>QUARTERLY</code>, <code>MONTHLY</code></td></tr><tr><td><code>UserEntitlementType</code></td><td><code>ROLE</code>, <code>GROUP</code>, <code>RESOURCE</code>, <code>ORGANIZATION</code></td></tr></tbody></table>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs-beta.openiam.com/segregation-of-duties.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
