> For the complete documentation index, see [llms.txt](https://docs.openiam.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.openiam.com/administration-guide/governance/sod/sap-sod-analysis.md).

# SAP role and SoD analysis

Activate OpenIAM's shipped SAP SoD content against real SAP entitlement data — the readiness check, the transaction-code naming gap that makes activation match nothing, and what the analysis can and c

## What this is, and when you need it

OpenIAM ships a catalogue of **SAP-derived segregation-of-duties rules**: 360 rules across ten `SOD_RULE_SET` rows, expressed as conflicts between named SAP transaction codes, organized by SAP module and mapped to named control frameworks. Activating a rule set turns each rule into a real `SOD_POLICY` with two segments, which the ordinary OpenIAM SoD engine then evaluates and enforces.

Read this page before you activate any of it, because the boundary of what it analyses is narrower than the name suggests, and because the shipped content and the shipped SAP synchronization do not match each other out of the box. Get that wrong and activation creates 110 empty roles and detects nothing, forever.

Everything mechanical about policies, segments, thresholds and the Inactive to Shadow to Enforced ladder is on [SoD policies and rule sets](/administration-guide/governance/sod/sod-policies-and-rule-sets.md), and the activation procedure itself is [Activate an SoD rule set](/administration-guide/governance/sod/sod-policies-and-rule-sets/activate-an-sod-rule-set.md). This page is the SAP-specific layer and does not restate them.

## At a glance

|                          |                                                                                                                                                                       |
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **You will end up with** | One shipped SAP rule set in `SHADOW`, its 30 or 45 policies matched against real SAP entitlements, and a classified conflict backlog                                  |
| **Where**                | **Access Control → Segregation of Duties → Rule Set Catalog** (`/webconsole/segregation-of-duties`)                                                                   |
| **You need first**       | One managed system per SAP system and client; SAP account-to-person correlation done; OpenIAM entitlements whose **names** are transaction codes                      |
| **Takes**                | Hours to days on the entitlement naming; 15 minutes on the activation itself                                                                                          |
| **Reversible**           | **Partly** — deactivating stops enforcement, but entitlements activation created are not removed, and remediation you carry out in SAP is not undone by anything here |

## Before you begin

Identify the rule set by its `EXTERNAL_KEY` and decide US or EU edition — the paired editions detect the same conflicts and differ only in control narrative, so the choice is which control language your auditor reads. The full catalogue, with rule counts, modules and framework strings, is in [SoD rule and policy reference](/administration-guide/reference/sod-rules-and-rule-sets.md#the-ten-shipped-rule-sets).

**Do not activate both editions of the same vertical against the same managed system.** The rule keys collide by intent, `SOD_POLICY` is unique on `(SOD_RULE_SET_ID, RULE_KEY)` and not across sets, so you would get two active policies per conflict and every violation twice.

Read [Change configuration safely](/administration-guide/start/change-safely.md), and activate in **Shadow**, always.

## Run the analysis

{% stepper %}
{% step %}

### Work the readiness check

Every row here has stopped an SAP rollout. Answer all of them before you open the activation dialog.

| Question                                                | Answer it with                                                                                                                                     |
| ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| Which SAP landscape and client is this managed system?  | The `MANAGED_SYS` row you will select in the activation dialog. One per system and client                                                          |
| Are SAP entitlements in OpenIAM as roles or as groups?  | Decides the create-as type. Getting it wrong creates everything                                                                                    |
| Are they attached to that managed system?               | `SELECT NAME, MANAGED_SYS_ID FROM ROLE WHERE NAME IN ('FK01','FK02','F110')` — a `NULL` managed system is not a match                              |
| Are the names transaction codes, or SAP role names?     | The gap described under [How SAP data has to look](#how-sap-data-has-to-look). Sample three names from the rule set and query for them             |
| Is every SAP account correlated to a person?            | An uncorrelated account cannot violate anything; a shared or technical account with a conflict needs an owner before the violation has a recipient |
| Are composite-role and business-role paths represented? | They are only evaluated through the authorization graph. Rebuild it after a bulk import                                                            |
| Are the memberships currently effective?                | Date filters are absolute — check `START_DATE` and `END_DATE` on the memberships                                                                   |
| When did reconciliation last complete cleanly?          | A partial import produces a clean-looking report with no findings, which is the worst possible output                                              |

Then prove the pipeline on one bounded population before you widen it: one known-clean identity and one known conflicting identity, and confirm that **only the second** is detected. A run with no findings means nothing until the positive control fires.
{% endstep %}

{% step %}

### Preview against the SAP managed system, with the right create-as type

**Access Control → Segregation of Duties → Rule Set Catalog**. Filter by region and vertical, open the candidate, and choose **Activate selected**.

Two choices in the dialog decide everything: the **Target managed system** — the SAP system and client — and the concrete type generic `ENTITLEMENT` references become. Set the second to whatever your SAP entitlements actually are; `ROLE` is only the default, not a recommendation.

{% hint style="warning" %}
**A generic `ENTITLEMENT` reference resolves against exactly one object type, not both** — the create-as type you choose here, which defaults to `ROLE`. So if your SAP entitlements are OpenIAM **groups** and you leave the default, nothing matches and everything is created. Run the preview once as `ROLE` and once as `GROUP` and compare the *will be created* counts; the preview is non-destructive, and the difference is the answer.
{% endhint %}

Matching is also scoped hard to the chosen managed system. Only candidates whose managed system *is* the activation target are considered; a same-named role in another managed system — **or with no managed system at all** — is not a match, and a duplicate is created in the target instead. SAP entitlements imported without a managed system association therefore look absent to activation.
{% endstep %}

{% step %}

### Read the *will be created* count as a pass or fail gate

This is the SAP-specific reading of the preview. Compare *entitlements matched* against *entitlements will be created* against the distinct transaction-code count for that set: **110** for either Manufacturing edition, **88** Financial Services, **57** Plant Maintenance, **47** Basis, **35** HR & Payroll.

**If&#x20;*****will be created*****&#x20;is close to that number, stop.** Nothing in your OpenIAM data matches the rule set and you are about to create a set of orphan entitlements that will never detect anything. Go back to the naming decision below.

*Ambiguous* means several same-named candidates matched and the first was used — in SAP terms, usually the same transaction code imported from two clients into one managed system. Disambiguate the names, separate the clients into separate managed systems, or override the reference. *Needs manual* is only ever an `ORGANIZATION` reference, and the shipped SAP content has none.
{% endstep %}

{% step %}

### Activate in Shadow, excluding the over-length rules

Choose **Shadow — all policies Soft (report only)**. Every generated policy is forced `SEVERITY = SOFT` with exceptions on, regardless of `riskLevel`, so nothing blocks. `SOD_RULE_SET.STATUS` becomes `SHADOW` with `ACTIVATED_AT` and `ACTIVATED_VERSION` stamped.

Restrict `ruleKeys` to the rules you confirmed — and on five of the ten sets, exclude the rules whose `businessRisk` text is longer than the column that stores it: `PM-FL-001`, `PM-WO-004`, `PM-VE-001`, `MFG-PP-001` and `FS-LN-006`. See [the length defect](#nine-rules-are-longer-than-their-column) below.
{% endstep %}

{% step %}

### Run detection and classify every hit

**Detect users** on the Violations tab, or **Run now** on Scheduled Detection. The first result is your backlog: how many people already hold each SAP conflict. See [SoD detection and violations](/administration-guide/governance/sod/sod-detection-and-violations.md).

Classify each hit before remediating any of it, because in SAP most first-run hits are not what they look like.

| Classification             | What it looks like                                                                         | What to do                                                                                                                              |
| -------------------------- | ------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------- |
| Confirmed conflict         | Both segments held, transactions genuinely usable                                          | Remediate per the rule's `remediation` text                                                                                             |
| Authorization-restricted   | Transactions held but restricted to different company codes or activities                  | OpenIAM cannot see this. Record the SAP owner's decision, with date and evidence, as a `SOD_MITIGATING_CONTROL` — not as a deleted rule |
| Mapping defect             | A transaction resolved to the wrong entitlement — check for *ambiguous* in the preview     | Fix the name or the reference, resync                                                                                                   |
| Stale data                 | Memberships end-dated in SAP but not yet reconciled, or the graph not rebuilt after import | Reconcile, rebuild the graph, re-detect                                                                                                 |
| Legitimate and unavoidable | Small finance team, no headcount to split the duty                                         | Mitigating control plus a review frequency, and put the review in a certification campaign                                              |

Nothing in the product chases a mitigating control review: `REVIEW_FREQUENCY` and `EXPIRATION_DATE` on `SOD_MITIGATING_CONTROL` are recorded, not enforced.
{% endstep %}

{% step %}

### Enforce, knowing exactly what turns hard

**Enforce** re-derives every policy's severity from its risk tag: only `SOD_RISK_CRITICAL` becomes `HARD`, with exceptions off. For the shipped SAP content that is a known count per set — **15** rules for each Manufacturing and Financial Services edition, **10** for each HR, Plant Maintenance and Basis edition, **120** across the whole catalogue.

Those are the policies that will start refusing provisioning saves with `SOD_POLICY_VIOLATION`, across every path including access-request fulfilment and business rules. Clear or mitigate every outstanding Critical conflict first; a Critical policy has no per-user exemption path once enforced.
{% endstep %}
{% endstepper %}

## Verification

| Claim                                           | Evidence                                                                                                                                                                                        |
| ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| The catalogue is present and untouched          | `SELECT EXTERNAL_KEY, VERSION, STATUS, SOURCE FROM SOD_RULE_SET WHERE SOURCE = 'OPENIAM_OTB'` returns ten rows, all `INACTIVE`, `openiam:mfg-us` and `openiam:mfg-eu` at `1.1.0`                |
| A rule set really holds the rules you expect    | The catalogue card's rule count and module chips, both computed live from `RULES_JSON`; under break-glass, `SELECT JSON_LENGTH(RULES_JSON, '$.rules') FROM SOD_RULE_SET WHERE EXTERNAL_KEY = ?` |
| Your SAP entitlements are findable by the rules | `SELECT NAME, MANAGED_SYS_ID FROM ROLE WHERE NAME IN ('FK01','FK02','F110')` (or `GRP`) returns rows whose `MANAGED_SYS_ID` is the activation target                                            |
| Activation matched instead of creating          | The preview summary's *entitlements matched* dominates *will be created*, and per-reference statuses read `MATCHED`                                                                             |
| The set activated                               | Audit `ACTIVATE_SOD_RULE_SET`, described `Activate SoD rule set <id> in SHADOW mode`; `SOD_RULE_SET.STATUS`, `ACTIVATED_AT`, `ACTIVATED_VERSION`                                                |
| Policies carry their SAP provenance             | `SELECT RULE_KEY, MODULE, RISK, POLICY_THRESHOLD FROM SOD_POLICY WHERE SOD_RULE_SET_ID = ?` — one row per activated rule, `MODULE` populated, `POLICY_THRESHOLD = 2`                            |
| Shadow really is non-blocking                   | Every generated policy has `SEVERITY = 'SOFT'` and `EXCEPTIONS_ALLOWED = 'Y'`                                                                                                                   |
| Detection ran and found the population          | Documents in the `user-violated-sod-policy` OpenSearch index; `SOFT_SOD_POLICY_VIOLATION_DETECTION` audit entries                                                                               |
| The positive control fired                      | Your known-conflicting test identity appears on the Violations tab and the clean one does not                                                                                                   |
| Indirect paths are being evaluated              | A user who holds both sides only through a composite role is detected, with the drill-down showing `INDIRECT[...]` contributions                                                                |
| Enforcement hardened only the Criticals         | After `ENFORCE_SOD_RULE_SET`, `SEVERITY = 'HARD'` on exactly the policies whose `RISK` is `SOD_RISK_CRITICAL` — 15 or 10 per set                                                                |
| A Critical rule actually blocks                 | Granting both sides to a disposable identity fails with `SOD_POLICY_VIOLATION` and one `HARD_SOD_POLICY_VIOLATION_DETECTION` entry                                                              |
| The SAP evidence pack is complete               | A `GENERATE_SOD_REPORT` CSV including `SOD_POLICY_RISK`, `SOD_MITIGATING_CONTROL`, `USER_IS_MC_MANAGER` and `USER_IS_MC_OWNER`                                                                  |

## When it goes wrong

Generic activation problems — an ambiguous match, a read-only shipped set, a severity that reverted on `Enforce` — are on [Activate an SoD rule set](/administration-guide/governance/sod/sod-policies-and-rule-sets/activate-an-sod-rule-set.md#when-it-goes-wrong). These are the SAP-specific ones.

| Symptom                                                       | Cause                                                                                                                                                       | Fix                                                                                                                                                                                               |
| ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Activation preview says every reference will be created       | The rule set matches transaction codes; your OpenIAM entitlements are named after SAP roles (`AGR_NAME`)                                                    | Import transactions as entitlements, or rewrite the rule `name` values as `CUSTOM_UPLOAD`                                                                                                         |
| Activation created 110 new roles and detection finds nothing  | Same cause, already committed. The created roles have no members                                                                                            | Deactivate the set, delete the orphan `ACCESS_ROLE` roles, fix the naming, re-activate                                                                                                            |
| Nothing matched and your SAP entitlements are groups          | A generic `ENTITLEMENT` reference resolves against **one** type only — the create-as type, default `ROLE`                                                   | Set the activation type to `GROUP`, and re-run the preview to confirm before committing                                                                                                           |
| Activation fails, *Data too long for column 'BUSINESS\_RISK'* | Nine shipped rules exceed `SOD_POLICY.BUSINESS_RISK VARCHAR(500)`                                                                                           | Clear the per-rule checkboxes for `PM-FL-001`, `PM-WO-004`, `PM-VE-001`, `MFG-PP-001` and `FS-LN-006` in the activation dialog, or clone the rules and shorten the text                           |
| A policy's business risk text stops mid-sentence              | Same rules, on a database in non-strict SQL mode                                                                                                            | As above                                                                                                                                                                                          |
| `authObjects` vanished from a rule you imported               | Import silently drops properties it does not recognise, and `authObjects` is one of them                                                                    | Carry the objects in `controlObjective` or `description`                                                                                                                                          |
| No screen shows authorization objects                         | Nothing in the product reads them                                                                                                                           | Expected. Do not build a control on object-level analysis                                                                                                                                         |
| Conflicts held through composite roles are missed             | Indirect hits come from the authorization graph, which is stale after a bulk import — or `org.openiam.sod.check.across.indirect.entitlements` was set false | Rebuild the authorization graph — see [Rebuild the authorization graph](/administration-guide/operations/rebuild-the-authorization-graph.md) — and confirm the property with the deployment owner |
| A user with both transactions is not flagged                  | The memberships are future-dated or end-dated; the date filter is absolute                                                                                  | Check `START_DATE` and `END_DATE` on the user's memberships                                                                                                                                       |
| The same conflict appears twice per user                      | Both the US and EU edition of one vertical are active; rule keys are unique per set, not across sets                                                        | Deactivate one edition                                                                                                                                                                            |
| Enforcing broke SAP provisioning across the population        | 15 (or 10) Critical policies per set became `HARD` with outstanding violations                                                                              | Set the offending `SOD_POLICY.ACTIVE = 'N'` to unblock, remediate, re-enforce                                                                                                                     |
| The SAP sync configuration does not run                       | The shipped `SYNCH_CONFIG` rows point `ATTRIBUTE_NAMES_LOOKUP` at `/sync/SAPSyncAttributes.groovy`, which does not ship                                     | Treat those rows as examples; supply your own lookup script                                                                                                                                       |
| The shipped SAP managed system does nothing                   | `MANAGED_SYS` `200` ships `IS_ACTIVE = 'N'`                                                                                                                 | Configure and activate it, or create your own per landscape and client                                                                                                                            |

## How SAP data has to look

This is the section that decides whether activation produces analysis or 110 empty roles.

OpenIAM seeds one SAP managed system, and it is **not active**:

| Object                | Shipped value                                                                                                                 | Since   |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------- |
| `PROVISION_CONNECTOR` | `CONNECTOR_ID = '200'`, `NAME = 'SAP CONNECTOR'`, `METADATA_TYPE_ID = 'SAP_Connector'`, `CONNECTOR_QUEUE = 'SAP_Connector_1'` | 4.0.0.0 |
| `MANAGED_SYS`         | `MANAGED_SYS_ID = '200'`, `CONNECTOR_ID = '200'`, `RESOURCE_ID = '200'`                                                       | 4.0.0.0 |
| … renamed             | `NAME = 'SAP Managed System'`, `DESCRIPTION = 'SAP S4 Hana Managed System'`, `USER_ID = NULL`                                 | 4.1.8.0 |
| … disabled            | `IS_ACTIVE = 'N'`                                                                                                             | 4.1.9.0 |
| … dated affiliations  | `SUPPORTS_DATE_FOR_AFFILIATIONS = 'Y'`                                                                                        | 4.2.1.6 |
| `RES`                 | `RESOURCE_ID = '200'`, `RESOURCE_TYPE_ID = 'MANAGED_SYS'`, `NAME = 'SAP'`, `COORELATED_NAME = 'SAP'`                          | 4.0.0.0 |
| `METADATA_TYPE`       | `TYPE_ID = 'SAP_Connector'`, `GROUPING = 'CONNECTOR_TYPE'`, display name *SAP Connector*                                      | 4.0.0.0 |

Find all of it under **Provisioning → Managed System**, filtered to `SAP Managed System` — its **Active** flag is off, which is why it does nothing until you configure and enable it.

Two example `SYNCH_CONFIG` rows ship against it, and they are where the naming problem becomes concrete:

| `NAME`           | `SYNCH_TYPE` | `QUERY`                      | `MATCH_FIELD_NAME` to `MATCH_SRC_FIELD_NAME` | Transformation script                              |
| ---------------- | ------------ | ---------------------------- | -------------------------------------------- | -------------------------------------------------- |
| SAP ROLE Example | `ROLE`       | \`GROUP\_TYPE=AGR            | FILTER=AGR\_NAME LIKE '?'\`                  | `NAME` to `AGR_NAME`                               |
| SAP USER Example | `USER`       | `FIRSTNAME:ADDRESS LIKE '?'` | `PRINCIPAL` to `USERNAME`                    | `sync/user/sap/SAPUserSampleTransformation.groovy` |

Open `sync/role/sap/SAPRoleSampleTransformationScript.groovy` in Groovy Manager and the working part of it is four lines: it sets the OpenIAM role's name from the SAP column `AGR_NAME` and its description from `AGR_TEXT`. That is all it does.

{% hint style="warning" %}
**Read those two together: the shipped sync creates OpenIAM roles named after SAP&#x20;*****roles*****&#x20;(`AGR_NAME`, for example `Z_FI_AP_CLERK`), and the shipped rules match on SAP&#x20;*****transaction codes*****&#x20;(`FK01`). Out of the box, nothing matches.** Activate `openiam:mfg-us` against a managed system populated that way and all 172 of its entitlement references resolve *will create*, producing 110 brand-new roles — one per distinct transaction code — with no members, no provisioning and no owner. Detection then finds zero conflicts forever, because nobody holds the new roles.

You have to close that gap deliberately, one of three ways:

1. **Bring transactions in as entitlements.** Extend the role transformation, or add a second synchronization, so each transaction code reachable from a role becomes an OpenIAM entitlement named exactly `FK01`, and grant it where the role grants it. This is the only option that makes the shipped rules work unchanged.
2. **Rewrite the rules in terms of your role names.** Export the set's `RULES_JSON`, replace each entitlement `name` with the SAP role or business role that carries that transaction, and re-import as `CUSTOM_UPLOAD`. Cheaper, and it moves the transaction-to-role mapping into your rule content, where it needs its own review cycle.
3. **Override references at activation.** The preview dialog's per-entitlement overrides point a reference at an entitlement you already have. Workable for a handful of rules; a 45-rule Manufacturing set carries 172 references and is not a manual job.

The `SYNCH_CONFIG` rows also name `/sync/SAPSyncAttributes.groovy` as their `ATTRIBUTE_NAMES_LOOKUP`, and **that script does not ship** — look for it in Groovy Manager and it is not there. The two rows are examples to copy and complete, not working configurations. See [Set up a synchronization](/administration-guide/lifecycle/synchronize-and-import-data.md).
{% endhint %}

### What OpenIAM evaluates

For each user, OpenIAM assembles four sets of entitlement ids from that user's **direct, date-filtered memberships** — their roles, their groups, their resources and their organizations. In every case the filter is the same and it is absolute: a membership counts only when its start date is empty or already past, and its end date is empty or not yet reached.

Every **active** `SOD_POLICY` is then evaluated against those four sets. Per segment, OpenIAM counts the direct hits first, and then — only when `org.openiam.sod.check.across.indirect.entitlements` is true, which is its **default** — walks the authorization graph for indirect hits as well.

Three facts follow, and each has bitten an SAP rollout:

* **A future-dated or lapsed SAP role assignment is invisible to SoD.** The date filter is absolute. A role granted with a start date next Monday does not conflict today.
* **Composite-role and business-role nesting is covered by the graph, not by the membership tables.** A stale authorization graph therefore *under-reports* conflicts held only through nesting. Rebuild it after a bulk SAP role import — there is no Webconsole screen for the rebuild, so follow [Rebuild the authorization graph](/administration-guide/operations/rebuild-the-authorization-graph.md), and see [Search indexes and the authorization graph](/administration-guide/reference/search-indexes.md) for what the graph holds.
* **`org.openiam.sod.check.across.indirect.entitlements` has no `SYS_PROP` row**, so you will not find it under **Administration → System Configuration**. It carries a built-in default of `true` and can only be overridden in the deployment's property layer. That means you cannot confirm its live value from the Webconsole: if you need to know, ask the deployment owner, or prove it behaviourally with the indirect positive control in the Verification table above. Set false, it silently reduces SAP analysis to direct grants.

The Violations drill-down splits each contribution into direct and indirect, which is what the **Is direct violation** column shows and what the `DIRECT[...]` and `INDIRECT[...]` lines in the CSV report record. For SAP that column answers "was this transaction granted to the person, or inherited through a composite role?" — which decides who remediates.

## What this content analyses, and what it does not

The boundary matters more here than anywhere else in this guide, because the words "SAP GRC" set expectations this content does not meet.

**What it is:**

* A shipped, versioned, framework-mapped SAP conflict library — the analysis content you would otherwise spend months writing, with the control objective, business risk and remediation text already drafted in audit language. `MFG-FI-001` says it exactly: remove `F110` from anyone with `FK01` or `FK02`, or require dual approval on payment runs.
* Detection and prevention over **OpenIAM entitlements whose names match SAP transaction codes**, using the same engine, the same violation index, the same reports and the same enforcement ladder as any other SoD policy.
* Coverage of indirect entitlement paths through the authorization graph, so a conflict held through a nested role is found — subject to the caveats above.
* A reporting axis: each rule's `module` is copied to `SOD_POLICY.MODULE` and indexed, so "all FI conflicts" is a query rather than a spreadsheet. `controlObjective` is what an auditor reads and is the field to reword for your own control catalogue.

**What it is not:**

* **Not an SAP authorization-object analyser.** Every rule carries an `authObjects` list naming the SAP objects behind the conflict (`F_LFA1_BUK`, `S_USER_GRP`, `P_ORGIN`). The product parses none of it. No field value, no company code, no activity (`ACTVT`) is evaluated anywhere.
* **Not an SAP-connected analyser.** It reads OpenIAM's own role, group, resource and organization memberships. It never calls SAP, never reads `AGR_1251`, `USOBT`, `USOBX` or `AGR_USERS`, and does not resolve which transactions a role actually contains. If your OpenIAM data does not represent the transactions, the analysis finds nothing.
* **Not a role-content simulator.** OpenIAM does simulate several things — an activation preview before a rule set creates anything, Shadow as a report-only run of enforcement, a re-sync preview, and **Preview impacted users** on business rules, all of which are set out under [What you can simulate before you commit](/administration-guide/governance/sod/sod-policies-and-rule-sets.md#what-you-can-simulate-before-you-commit). What none of them does is read the *contents of an SAP role* and tell you what granting it would introduce, because the product never reads SAP role contents at all. Preventive evaluation happens at provisioning time against a real user's resulting entitlement set, so to test a candidate SAP role you grant it to a disposable identity and see whether the save is refused.
* **Not an SAP compliance attestation.** All ten rule sets ship `STATUS = 'INACTIVE'`. Nothing is detected or blocked until you activate, and activation asserts nothing about your SAP design.

Detecting `FK01` plus `F110` on one identity proves the mapped transaction combination is held. It does not prove the combination is exploitable — company-code restrictions in `F_LFA1_BUK` and `F_BKPF_BUK` may make it inert, and OpenIAM has no visibility of that. Say "transaction-level conflict detected", not "SoD violation confirmed in SAP", until an SAP security owner has looked at the authorizations.

### `authObjects` is parsed by nothing

{% hint style="danger" %}
**Every one of the 360 shipped rules carries a non-empty `authObjects` array, and the product discards all of it.** The rule properties OpenIAM reads out of `RULES_JSON` are `ruleKey`, `name`, `description`, `riskLevel`, `module`, `controlObjective`, `businessRisk`, `remediation`, `policyThreshold`, `severity`, `incomplete` and `segments`. `authObjects` is not among them; unknown properties are dropped without a warning.

**Confirm it yourself in two minutes:** export a shipped set, re-import the unmodified export as `CUSTOM_UPLOAD`, and export that. Every `authObjects` array will be gone.

Consequences to plan around:

* **No authorization-object matching happens.** OpenIAM will not correlate `F_LFA1_BUK` with anything, will not read authorization values from SAP, and will not narrow a conflict by company code. Any control that claims object- or field-level SoD analysis is not supported by this content.
* **It does not survive a round trip.** Import rewrites the JSON from the properties it understood, and the CSV, JSON and XML import templates have no column or element for it either.
* **It is not displayed.** No rule detail panel, report column or export carries the objects.

If you need the objects retained as evidence, put them in `controlObjective` or `description`, which are real columns — mind the 500-character limit on `CONTROL_OBJECTIVE`. Treat the arrays in the shipped content as reference documentation for the SAP security owner reviewing the rule, which is what they are.
{% endhint %}

### Nine rules are longer than their column

{% hint style="danger" %}
**Nine shipped rules carry a `businessRisk` string longer than the column that stores it.** `SOD_POLICY.BUSINESS_RISK` is `VARCHAR(500)`, and activation copies the rule's `businessRisk` onto the policy without truncating it. These nine exceed it:

On a database in strict SQL mode — the default on MariaDB 10.2+ and MySQL 5.7+ — activating `openiam:pm-us`, `openiam:pm-eu`, `openiam:mfg-eu`, `openiam:fin-services-us` or `openiam:fin-services-eu` for **all** rules fails on those rows with *Data too long for column 'BUSINESS\_RISK'*; in non-strict mode the narrative is silently truncated mid-sentence. `openiam:mfg-us`, both HR sets and both Basis sets are unaffected.

Work around it by activating a confirmed subset: pass `ruleKeys` on the activation request (the per-rule checkboxes in the preview dialog) with the affected keys excluded, land the rest, then handle those rules by cloning the set as `CUSTOM_UPLOAD` with shortened `businessRisk` text. Confirm against your release whether the column has been widened.
{% endhint %}

| Rule set                                             | Rule key     | `businessRisk` length |
| ---------------------------------------------------- | ------------ | --------------------- |
| `openiam:pm-us`, `openiam:pm-eu`                     | `PM-FL-001`  | 547                   |
| `openiam:pm-us`, `openiam:pm-eu`                     | `PM-WO-004`  | 511                   |
| `openiam:pm-us`, `openiam:pm-eu`                     | `PM-VE-001`  | 508                   |
| `openiam:mfg-eu`                                     | `MFG-PP-001` | 515                   |
| `openiam:fin-services-us`, `openiam:fin-services-eu` | `FS-LN-006`  | 508                   |

## Related

* [Activate an SoD rule set](/administration-guide/governance/sod/sod-policies-and-rule-sets/activate-an-sod-rule-set.md) — the generic activation procedure, drift and resync
* [SoD policies and rule sets](/administration-guide/governance/sod/sod-policies-and-rule-sets.md) — the enforcement ladder and the severity override
* [SoD detection and violations](/administration-guide/governance/sod/sod-detection-and-violations.md) — the sweep and the digest
* [Work an SoD violation to closure](/administration-guide/governance/sod/sod-triage-remediation-and-evidence.md) — exemptions, mitigating controls and the CSV report fields
* [SoD rule and policy reference](/administration-guide/reference/sod-rules-and-rule-sets.md) — the ten catalogues, the rule JSON schema and the CSV import columns
* [Configure a managed system](/administration-guide/lifecycle/configure-managed-system.md) — setting up the SAP managed system the analysis scopes to
* [Search indexes and the authorization graph](/administration-guide/reference/search-indexes.md) — rebuilding the graph that indirect conflict detection depends on

*Applies to OpenIAM 2026.8.1. Last reviewed 7 August 2026.*


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

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

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.openiam.com/administration-guide/governance/sod/sap-sod-analysis.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
