Segregation-of-Duties Con
Detect users holding conflicting access rights and report SoD violations
Segregation-of-duties conflicts — one person who can both create a vendor and pay it — are invisible in standard Odoo, yet they are exactly what auditors and internal-controls frameworks demand you control. This module lets internal audit, finance-controls and IT-security teams define SoD rules as pairs of incompatible security-group sets with a risk level and rationale. The engine scans every internal user, follows implied group membership so nothing is missed, and flags anyone holding both sides of a rule. Conflicts flow through acknowledge/mitigate/accept with full chatter history, mitigating controls reduce residual risk, a scheduled scan auto-closes resolved conflicts, and every run is logged for point-in-time audit evidence — with one-click remediation and CSV-ready exports.
Key Features
Conflicting-duty rules
gb.sod.rule pairs two sets of res.groups (group_a_ids vs group_b_ids) with labels, a 1-4 risk_level and a rationale — for example Create Vendor vs Register Payment. A constraint blocks a group appearing on both sides, and a control owner is recorded for accountability.
Implied-group aware scan
scan() walks every internal, non-share res.users and calls _evaluate_user. Crucially _expand_implied transitively follows each group's implied_ids, so a user who effectively holds a duty through an implied group is still caught — not just direct membership.
Conflict lifecycle with auto-close
Each gb.sod.conflict runs open to acknowledged to mitigated/accepted via action_acknowledge, action_mitigate and action_accept_risk, all tracked on chatter. When a re-scan finds the user no longer holds both duties, action_auto_close resolves it with a timestamp — the record self-heals as roles change.
Mitigating controls and residual risk
gb.sod.control is a reusable library of preventive/detective/corrective measures with an effectiveness rating. residual_risk_level() on a rule lowers the inherent risk by the strongest attached control, so auditors see residual not just inherent risk for accepted conflicts.
One-click remediation and risk scoring
action_remove_side_b revokes the Duty-B groups straight off the user (via group_ids) and re-evaluates, auto-closing the conflict if cleared. get_user_risk_score sums a user's open-conflict risk weights, and action_view_user_conflicts shows every conflict for one person across all rules.
Scheduled scan with audit log
The _cron_scan_all job re-scans all active rules on a schedule. Every run writes a gb.sod.scan.log snapshot — trigger, rules and users scanned, new/open/closed and critical-open counts — giving auditors point-in-time evidence independent of the live, ever-changing conflict records.
Dry-run preview and conflict matrix
action_preview / preview_conflicts report how many conflicts a scan would find without persisting anything, ideal before publishing a new rule. build_conflict_matrix returns a user x rule grid and export_audit_rows produces flat dicts ready for CSV/XLSX audit packs.
Scan wizard and bulk handling
gb.sod.scan.wizard runs all active rules or a chosen subset, optionally limited to specific users. action_bulk_acknowledge clears a whole selection of open conflicts at once, and open_conflict_summary aggregates open conflicts by risk level for dashboards and KPIs.
Use Cases
Screenshots
Conflicts
Conflict Analysis
Mitigating Controls
Sod Rules
Scan History
Run Sod Scan
Why Choose This Module
Define Segregation-of-Duties (SoD) rules as pairs of incompatible permission sets (security groups) — for example "Create Vendor" vs "Register Payment", or "Post Journal Entries" vs "Manage Bank Accounts". The engine scans every internal user and flags anyone who holds both sides of a rule, producing an auditable conflict report with risk levels, owners and mitigation notes. No native Odoo feature covers this control.
Specifications
- Compatible: Odoo 18.0 / 19.0
- License: OPL-1
- Languages: English
- Author: Pokutsoft
- Dependencies: base, mail
- Support: support@pokutsoft.com
Update date: 2026-07-02