The governance model rapidvalue.eu →

Separation of duties and risk

Two questions sit next to each other in every governance review: which combinations of access must never land on one person, and who or what is risky right now. This page is how both are expressed — and, more usefully, what each one refuses to conclude.

A rule is a set of filters, not a table of pairs

A separation-of-duties rule declares two or more conditions, each a filter over entitlement attributes. An entitlement belongs to a side if it matches that side's filter. An identity violates the rule when it holds at least one active grant on each side.

Those filters use the same filter DSL that drives workflow triggers, dynamic group membership, audience conditions and scoping — a deliberate choice over the obvious alternative, a table of forbidden entitlement pairs. It earns its keep twice: administrators learn one syntax, and a rule describes a shape rather than an inventory. A pair table has to be extended by hand whenever a new entitlement is created that belongs on one side of an existing conflict, which nobody does, so it quietly stops describing the estate.

Conflicts span systems by construction. Sides resolve to entitlements, grants join back through accounts to the identity, and nothing in that path cares which connector a side lives on. A vendor-master permission in the ERP and a payment approval in a separate finance application is one violation on one person.

What one rule catches, and what it does not

Five rules ship seeded and enabled. Take the fraud one — Vendor master + payment approval, severity critical, referencing SOX 404 and COSO ICFR:

An identity holding SAP Vendor Master Maintenance and AP Payment Approval is flagged, whichever systems those live on. The finding names both grants, their systems and how each was obtained — a reviewer deciding which side to remove needs to know that one arrived through a role and the other was requested by hand.

Now the other half, because it decides whether you trust the number on the dashboard:

A rule can also be scoped by an identity-side filter, so a conflict that only matters for Finance is only evaluated for Finance.

Two guards that stop a rule being useless

Both sides must be non-empty. A rule is rejected at save if fewer than two conditions carry content. An empty filter matches every entitlement, so one empty side flags every identity holding two grants — a confident, comprehensive, worthless finding, and one that reads as a catastrophic compliance failure rather than as a typo.

An entitlement matching more than one side is dropped from all of them. A permission matching both the vendor and the payment pattern would otherwise occupy both sides at once, and a single grant on it would flag its holder for a conflict of one permission with itself. Such a permission is ambiguous, not two things. The same de-duplication runs in the enforcement gate — a detector and a gate disagreeing about who is in violation is worse than either being wrong alone.

Three actions, and what each does to access

Every rule carries one enforcement action. Three exist, all three are implemented, and the seeded rules ship on the mildest.

Enforcement happens at two points, answering different questions.

At request time, submitting an access request runs a pre-flight that expands both the requested entitlements and the identity's current holdings through their role and group hierarchies — a conflict hidden two levels inside a requested role is still a conflict. Anything that would create a violation under a block_no_exceptions rule is refused at submission with the rule named, since approving a request whose grant would be killed on arrival with no exception path wastes an approver's time. Conflicts under the other two actions ride along as warnings, so the approver decides with the conflict in front of them.

In reconciliation, access already held is handled where all access is handled. When an identity's expected access is recomputed, an enforcing rule annotates the conflicting entries — they stay in the expected set, marked blocked or overruled, because deleting them would erase the explanation. The apply path acts on the annotation: a blocked grant present in the target is revoked, an overruled grant that is absent is restored. The revocation is reversible, since the grant row survives for an approved overrule to put back.

Which side is blocked is decided rather than guessed, and an entire side goes so the conflict is genuinely broken. One side established and the other new: the new side goes, because the arriving access is the creep. Both established: the side with the most recent grant. All new: all of it. With three or more sides, the newest.

No automated resolution

The advisor finding for a violation has no one-click fix. Its apply action returns a refusal and an explanation, deliberately. Which side to remove is a business judgement: revoking the vendor-maintenance half and revoking the payment-approval half both satisfy the rule and have entirely different consequences for the person's job, and nothing in the data says which is right. The finding names the identity, the rule, both sides and how each grant was obtained; a person chooses, and the advisory closes itself once the conflict is gone. The asymmetry with the blocks above is intentional — a block is a policy decision taken in advance, with a published tie-break, whereas auto-resolution would be the platform making that call after the fact on its own.

Risk scores are weighted sums you can recompute

The identity risk score is a single number from 0 to 100: a sum of components, each a count multiplied by a per-unit weight, capped at a per-component maximum, with the total clamped to 100.

That is the whole model. No learned model, no behavioural baseline, no opaque scoring service — and that is the design position rather than a stage on the way to one. A score that drives revocation and prioritisation has to be defensible to the person it describes and to the auditor asking why. Every score stores its own breakdown, so "why is this 74?" is answered with arithmetic:

Component Count Per unit Cap Contribution
Critical SoD violation 1 20 60 20
Dormant privileged grant 4 10 25 25 (40 capped)
Dormant grant 3 3 15 9
Open critical advisor finding 1 15 30 15
Never reconciled, or not in 30 days 1 5 5 5
Total 74

Seventy-four falls in the high band (0–25 low, 26–50 medium, 51–75 high, 76–100 critical). Crossing into critical emits an event, so it can drive a workflow rather than waiting to be noticed on a dashboard.

Four properties matter more than the numbers:

Turning the score off stops the sweep and leaves the last computed values in place. Nothing is silently reset behind a toggle.

Two scores, two questions

The identity score answers who is risky. A separate score on each entitlement answers what is risky: privileged access spread across many holders, the share of holders who are dormant, membership of a tracked toxic combination, holders who are themselves high-risk, and exposure through a business-critical application. Same arithmetic, different subject. Neither replaces the administrator-set inherent risk level of an entitlement — that is a judgement about what the permission is, while the resource score measures what has happened around it. An entitlement classified low-risk that has accumulated three hundred holders, most of them dormant, is exactly the case worth seeing.

One eligibility rule, or the number stops meaning anything

The invariant most worth explaining to a reviewer is not about scoring at all: the finding and the score must share their eligibility predicate.

Dormancy proves it. A grant with no last-used timestamp is only dormant if the platform can actually observe activity on that system and has looked at least once; otherwise the empty value means "not tracked", and reading it as dormancy is fabrication. That gate is described in full under non-human identities and ownership.

The point is what happens when two consumers of one signal drift. The advisor's dormancy detector and the risk score's dormancy components once held byte-identical copies of the rule, kept in step by a comment asking the next person to remember. Once they diverge, an administrator sees a score of 74 with dormant grants itemised in its breakdown, opens the inbox it points at, finds nothing — and cannot tell which surface is lying. Both now compute from one shared implementation.

So: change an eligibility predicate — a threshold, a capability gate, a scope — and change it in every path that reads it. A score the inbox cannot account for is worse than no score.

Known edges, published rather than discovered


Further reading: