A Segregation of Duties conflict count is driven more by the ruleset you picked than by the security you are measuring. Swap one ruleset variant for another and the number moves further than any redesign would move it.

On one client, changing only the ruleset variant moved the result from about 870 role-risk pairs to 353. On another it moved from 1,814 to 856. Nothing about either client's security changed between those two numbers. Only the measuring instrument changed, and it changed the answer by more than two to one.

The number you report is a choice, not a measurement

An SoD engine joins each role's access to a ruleset that defines which pairs of business processes conflict. The ruleset decides what counts. If the ruleset is broad, the count is high. If it is narrow, the count is low. The underlying access is the same either way.

That makes the ruleset the single largest lever over the headline, larger than the security work the report is supposed to be evaluating. A redesign might remove a few dozen conflicts. The choice between two ruleset variants moved one estate by more than 500 pairs. Report a conflict count without disclosing and defending the ruleset behind it and you have reported a preference dressed as a finding.

Inherited rulesets are frequently contaminated

Off-the-shelf and inherited rulesets carry damage from wherever they were last edited. One ruleset in use had 48 business processes, and 46 of them contained, alongside their real content, blocks of unrelated menu items. A purchase-order process contained HR recruitment. A transfer-order process contained system administration. Those blocks look like other standard processes filed under the wrong name, the residue of a ruleset edited inside a different company's tenant years earlier and never cleaned.

Contamination like that manufactures conflicts out of nothing. If "purchase orders" secretly contains recruitment menu items, then anyone who can raise a purchase order and anyone who touches recruitment can be flagged as conflicting, for a conflict that does not exist in reality. One absurd flag is all it takes. An auditor who sees a purchase-order process firing on HR recruitment stops trusting the purchase-order finding, then stops trusting all of them.

A tempting shortcut makes this worse. Falling back to the ruleset's default group as the "core" set is not a validated narrowing. The default group name is just the tool's default label, not a curated list, and some objects sit in more than one process, so a single menu item can fire several risks. Narrowing to it can hide real conflicts, which in an audit is the worse failure. That is why a contaminated-but-broad count and a default-group count sitting side by side, say 870 next to 353, honestly say "we do not yet know which is real" rather than offering either as the answer.

Two technical traps that silently distort the count

Two definitions have to be right or the count is wrong regardless of the ruleset.

Write access is not simply "a write verb is granted." It has to be a write verb granted and not denied, AND read not denied. Some clients write their restrictions as read-only denies rather than as explicit write removals, so an engine that ignores read denies will count write access that the client has already locked down. On one client, ignoring read denies reported conflicts the client had already mitigated, until the write definition was corrected to respect those denies. Deny has to win per verb and across all of a user's roles, because a deny on one role suppresses a grant on another.

The second trap is scope. A ruleset built on menu items is blind to every access path that does not go through a menu item: service operations, data entities, and direct table grants. A user can hold a conflicting capability through a data entity and never appear in a menu-based count. The report is not wrong about what it saw. It is silent about what it cannot see, and that silence has to be stated, not assumed away.

Fix the instrument before you quote it

The order of operations is not optional. Clean and validate the ruleset first. Strip the contaminated cross-filed menu items, resolve the risks marked for further review or left blank, and drop any mitigation mapping that belongs to a different company's tenant. Confirm the write definition handles read-only denies and applies deny per verb across all roles. State plainly that menu-based scope omits service operations, data entities, and direct table grants. Only then is a conflict number fit to show anyone.

There is a licensing-style question underneath all of this that is easy to skip: whether a ruleset authored inside another company's tenant is even licensed for use on this client. Disclose its provenance along with its contents.

Bottom line

Fix and disclose your ruleset before you report a single conflict number. The count is dominated by the ruleset, inherited rulesets are routinely contaminated with content from other tenants, and a menu-based ruleset is blind to service operations, data entities, and direct table grants. An auditor who catches one absurd flag, a purchase-order process firing on HR recruitment, will distrust every number you gave them, and they will be right to. The conflict count is only as credible as the ruleset is clean and disclosed.

Frequently asked questions

Which count is the real one, the broad one or the narrow one?

Neither, until the ruleset is cleaned. A broad contaminated count overstates and a narrow default-group count can hide real conflicts. Showing both side by side is an admission that the instrument is not yet trustworthy, not a menu to pick from.

Why does read-only deny matter so much?

Some clients express "no write access" as a read-only deny rather than removing the write verb. An engine that checks only granted write verbs counts those users as having write access they do not have, inflating conflicts the client already mitigated.

Is a menu-based ruleset good enough?

It is a floor, not a ceiling. It misses service operations, data entities, and direct table grants, so it can only undercount through those paths. Disclose the limitation with every number.