Iiq Sod Exception Tracker
A browser-runnable dashboard that turns IIQ's flat policy-violation list into a full exception register — surfacing open violations, allowed exceptions with expiry countdowns, and delegated decisions…
IIQ SOD Exception Tracker
A browser-runnable dashboard that turns IIQ's flat policy-violation list into a full exception register — surfacing open violations, allowed exceptions with expiry countdowns, and delegated decisions in one filterable view.
Date: 2026-07-13 Type: App Theme: Detect + Protect Platform: SailPoint IdentityIQ Status: Idea
What it is
A single-page HTML/JS/CSS application (no build step, no auth, no CDN) that loads IIQ PolicyViolation records from a JSON feed and presents them as an exception register. The app shows every violation's current status (Open, Allowed, Delegated, Complete), the age of each violation since it was first detected by the Refresh Identities task, and — critically — a countdown to the expiry date of any allowed exception. Violations whose exception windows close within 14 days trigger an amber alert banner. Clicking any row opens a slide-in detail panel with the conflicting entitlements, the business justification comment, and the compensating control on record.
Who it serves
IAM engineers and GRC/compliance officers who run quarterly SOX access reviews against an IIQ environment with 50k+ identities and dozens of active SOD policies. They need to answer two questions at the start of every audit cycle: "Which violations are still open and unaddressed?" and "Which allowed exceptions are about to expire and need renewal or remediation?" Today they piece this together by exporting the policy violations report and building a spreadsheet. This app replaces that manual step.
The IIQ pain it addresses
IIQ's native Policy Violations page (accessible via the MyWork menu and via Quicklinks) surfaces only the violations for which the logged-in user is the violation owner. Administrators can see the full set, but only through a paginated flat list — there is no view that simultaneously shows age, expiry status, and compensating control for all violations across all policies. The "Allow" action lets a reviewer set an allowedUntil date (configurable in Compliance Manager global settings under Default Duration for Exceptions), but once that date is set, there is no dashboard that aggregates all upcoming expiration deadlines and alerts the team before exceptions lapse silently. At scale — 20+ active SOD policies, 500+ applications, violations re-evaluated every Refresh Identities run — exceptions expire unnoticed, violations re-appear in the open queue, and auditors ask why the team didn't track them.
How it works
- Load: The app fetches
sample-data.jsonon startup. In production, this feed is produced by a scheduled IIQ Report task queryingspt_policy_violation,spt_identity, and a custom extended-attribute for compensating controls, then emitting the JSON to a static export path. - Summary bar: Six clickable cards (Total, Open, Allowed, Expiring <30 Days, Delegated, Complete) filter the table and are computed dynamically from the loaded dataset.
- Expiry alert: A banner appears automatically if any Allowed violation's
allowedUntildate is within 14 days of today. It names each impacted identity and policy so the team can act before the exception lapses. - Table: Violations are shown in a sortable, filterable table. Age is colour-coded (green < 30 days / amber 30–90 days / red > 90 days). Expiry dates colour-code as amber (≤14 days) or red (already expired). Free-text search covers identity name, ID, department, policy, rule name, application, and owner.
- Detail panel: Clicking any row slides in a full-detail panel showing the conflicting entitlement pair (application + entitlement name), the decision history (who allowed it and what justification was entered), and the compensating control on record.
What's in this folder
README.md— this filecover-image.png— card cover illustrationmetadata.md— workflow metadata sidecarrequirements.md— functional requirements and IIQ integration notesindex.html— single-page entry point, opens in any modern browser viafile://style.css— dark-theme stylesscript.js— data loading, filtering, sorting, and panel logic (vanilla JS, no dependencies)sample-data.json— 20 synthetic IIQ-shapedPolicyViolationrecords across Finance, IT, HR, and Cloud policies
How to run / read it
Open index.html in any modern browser. No server, no auth, no npm.
# If fetch() is blocked by browser security on file:// URLs, start a minimal server:
python3 -m http.server 8080
# then visit http://localhost:8080
The app's date calculations are pinned to 2026-07-13 so age and expiry values are stable against the sample data. Two violations (pv-006 and pv-016) expire within 14 days of that date, so the amber expiry alert banner should be visible on load.
Estimated impact
At a 500-connector IIQ shop managing 30+ active SOD policies, a compliance analyst typically spends 2–3 hours per audit cycle manually exporting violation data, building an exception register in Excel, and cross-checking which allowed exceptions are still within their approved window. This app reduces that to a 10-minute scan, saving roughly 4–6 hours per quarter per compliance analyst — and eliminates the class of audit finding caused by an exception expiring silently.
Why this fits an IIQ shop with 500+ connectors
At 500+ connectors, the number of entitlement-level SOD policies grows non-linearly: Finance policies conflict across SAP ECC, Workday, and Citibank Treasury; Cloud policies conflict across AWS IAM and GitHub; Security policies conflict across AD and firewall management tools. The flat list of violations is unmanageable without aggregation. The allowed-exception workflow is explicitly designed for large shops where some violations are structurally unavoidable (single approver in a regional team, staffing gap during a project) — but those shops also need the most disciplined expiry tracking. This app addresses the scale problem directly: it sorts by expiry soonest, colour-codes by age, and gives auditors a printable view of the full exception register without requiring access to the IIQ UI.
Sources
- Working with Policy Violations — SailPoint IdentityIQ 8.4 — violation lifecycle states (Open / Allowed / Delegated / Complete), the Allow action, configurable end dates, and re-appearance behaviour after exception expiry
- About Policies and Policy Violations — SailPoint IdentityIQ 8.4 — PolicyViolation object, violation owner resolution, and the policy evaluation triggered by Refresh Identities
- Policy Violation Work Items — SailPoint IdentityIQ — work item generation for violation decisions, delegation mechanics
- Compliance Manager — SailPoint IdentityIQ — Default Duration for Exceptions setting, Deprovision Items When Exception Expires option, and the Enable Allow Exceptions Popup flag that makes
allowedUntilconfigurable per reviewer - Enhancement: SOD Policy Audit Events — SailPoint Developer Community — community surfacing of the gap between what SOD audit events record and what compliance teams need (before/after values, material change tracking); grounded the motivation for a complementary exception-register view
- Policy Violations Not Detecting After Remediation Period — SailPoint Developer Community — confirmed community pain around violation lifecycle state management after Refresh Identities re-evaluates completed violations
Requirements
Requirements — IIQ SOD Exception Tracker
Purpose
A single-page browser app that surfaces all IIQ PolicyViolation records in one interactive dashboard — tracking violation age, exception (allow) status, expiry dates, and compensating controls — so an IAM engineer or compliance officer can monitor the full SOD exception register without digging through IIQ's per-identity view.
Functional Requirements
FR-01 Summary cards
- Display six clickable summary cards: Total, Open, Allowed (Exception), Expiring <30 Days, Delegated, Complete.
- Clicking a card filters the table to that status subset.
- Card counts are derived from the loaded violation dataset, not hard-coded.
FR-02 Expiry alert banner
- Show a dismissible amber alert banner when any Allowed violation expires within 14 days.
- Banner lists each impacted identity name, policy short-name, and expiry date.
- Banner is hidden when no violations meet the 14-day threshold.
FR-03 Filterable / sortable table
- Columns: Identity, Policy/Rule, Applications, Risk Score, Age, Status, Exception Expiry, Detail button.
- Filters: free-text search (identity name, identity ID, department, policy, rule, application, owner), Status dropdown, Policy dropdown (auto-populated), Age bucket (>90 days / 30-90 days / <30 days).
- Sort options: Risk descending (default), Risk ascending, Oldest first, Newest first, Expiry soonest.
- Age colouring: green < 30 days, amber 30–90 days, red > 90 days.
- Expiry colouring: amber if ≤14 days, red if already expired, slate otherwise.
FR-04 Detail panel
- Clicking any row or the "View ›" button opens a slide-in panel.
- Panel shows: identity detail, violation detail (policy, rule, status, owner, detected date, last-refreshed date), conflicting entitlements (application + entitlement name + description), and a status-specific section:
- Allowed: allowed-by, expiry date with day count, business justification comment, compensating control.
- Delegated: delegated-to party.
- Complete: resolved date and resolution note.
- Panel closes on Escape key, overlay click, or ✕ button.
FR-05 Data loading
- App loads
sample-data.jsonviafetch(). - All counts, filters, and display values are derived dynamically from loaded data.
- On fetch failure, table body shows a user-readable error.
FR-06 Accessibility
- Table rows are keyboard-focusable (tabindex="0") and respond to Enter key.
- Detail panel is a
role="dialog"witharia-modal="true". - Close button has an
aria-label.
Non-Functional Requirements
- No build step.
index.htmlopens in any modern browser viafile://URL or a local HTTP server. - No external dependencies. Vanilla JS (ES2020+), no npm, no CDN, no authentication.
- No hard-coded secrets.
sample-data.jsonuses synthetic identities, synthetic application names, and placeholder IIQ object IDs. - Today's date is pinned in
script.js(const TODAY = new Date('2026-07-13')) so age and expiry calculations remain accurate against the sample data when the app is opened in any future date. In a production integration, replaceTODAYwithnew Date().
IIQ Integration Notes (Production Path)
The sample data mirrors the shape of IIQ's PolicyViolation object. To populate this app from a live IIQ 8.4 instance:
- REST endpoint:
GET /identityiq/rest/policyViolations— returns the current user's visible violations. For an admin view, query thespt_policy_violationtable directly via an IIQ Report task or JDBC export. - Key fields:
status→ maps toOpen/Allowed/Delegated/Completein the UI.allowedUntil→ date field set when a reviewer clicks "Allow" with an end date (requires "Enable Allow Exceptions Popup" in Compliance Manager global settings).allowedBy→ the identity name of the reviewer who granted the exception.allowComments→ the text entered when the exception was granted.entitlementsToRemediate/relevantEntitlements→ the conflicting entitlement pairs.
- Refresh Identities task: violations are re-evaluated every time this task runs.
lastRefreshedDatein the sample data corresponds to the task's last-run timestamp fromspt_task_result. - Compensating controls are not a native IIQ field — they must be stored in a custom Identity or Application extended attribute and joined at query time.
Acceptance Criteria
- Opening
index.htmlrenders the full app with no console errors. - Summary card counts match the breakdown in
sample-data.json. - Filtering by Status "Open" shows only open violations.
- Sorting by "Expiry Soonest" places violations with the nearest
allowedUntilDatefirst; violations with no expiry appear last. - Clicking a row opens the detail panel; Escape closes it.
- The expiry alert banner appears (pv-006 and pv-016 both expire within 14 days of 2026-07-13).
- Free-text search for "SAP ECC" returns only rows where SAP ECC appears in an entitlement.
More from IAM Ideas