Separation of duties
Conflict sets that block or flag a role, group or entitlement combination. Where the check actually runs, and the one direct-assignment path it does not yet cover.
A conflict set names two or more roles, groups or entitlements that must never be held by the same person at the same time — the classic example is "can raise a payment" and "can approve a payment." Define one at /iam/governance/sod, and it is checked whenever this platform grants access through the two paths described below.
Block and flag
| Mode | What happens | What gets recorded |
|---|---|---|
block | The grant is refused outright. Nothing is applied. | Nothing — a refused grant is not treated as a violation, so no finding is written for a block. Only an audit entry, iam.governance.sod_blocked, naming the sets that matched. |
flag | The grant proceeds normally. | An open finding in iam_sod_findings, one per matching set, plus an iam.governance.sod_flagged audit entry. The finding stays open until an administrator marks it resolved. |
A conflict set needs a unique name, a mode (defaults to block if omitted), and at least two members, each a member_type of role, group or entitlement with its member_id. A set can be deactivated (is_active: false) without deleting it, which stops it being evaluated while keeping its definition and history.
Where the check actually runs
There are exactly two places a grant is checked against your conflict sets, and both are real, wired call sites — not a shared abstraction that only fires from one of them:
- The terminal approval step of an access request, for
roleandgrouprequests. A blocked request is rejected with the conflict's name as the decision note, before any grant is applied. - A direct assignment made outside a request — adding someone to a group, from the group's own membership screen, or App assignments' assignment screen — checked at the single point in the code each of those paths writes the membership row.
A bundle's own resource type is not evaluated as a unit either — see Entitlements and bundles for why its group items are still covered, just at the inner grant call rather than against the bundle as a whole.
How a conflict is actually detected
At the moment of a check, the platform reads what the person currently holds — their organisation role, their group memberships, and any entitlement recorded against them through a bundle assignment — and adds the proposed grant to that set. If two or more members of any active conflict set are now present together, that set has matched. A set with three members matches as soon as any two of them are held together; it does not require all three.
Findings
A finding is a flag-mode conflict that was allowed to proceed. It records the organisation, the conflict set, the user, and the proposed grant that triggered it. GET /organizations/{orgID}/governance/sod-findings?status=open lists only open ones; omit the filter to see resolved findings too. Resolving one — POST .../sod-findings/{id}/resolve — marks it closed with the resolving administrator's identity and a timestamp; it does not undo the grant that caused it, because flag mode never blocked that grant in the first place. Resolving a finding is a statement that you have reviewed the combination and accepted it, or fixed it by hand elsewhere.
Permissions
| Action | Permission required |
|---|---|
| View conflict sets or findings | iam:governance.read |
| Create or delete a conflict set, or resolve a finding | iam:governance.write |
What to do next
- Building a role that grants exactly enough — decide which role pairs are genuinely toxic before you define a conflict set around them.
- Access requests and resource owners — the one grant path where a role change is always checked.
- Entitlements and bundles — how a bundle's group items still run into this check.