Classic IGA tools count drift. DORA, NIS2, and SOX require evidence that you detected, assessed, and remediated drift — including the context of what the policy was at moment X. A count of "423 unapproved grants" is not evidence.
RapidValue IGA introduces per-grant snapshots with human-readable reasons. Every reconciliation run stores, per grant, exactly what the SOL (desired state) and IST (actual state) were at that moment, together with why they had that state. This transforms reconciliation from a tool output into an audit-evidence pipeline.
Ask a classic IGA tool: "Why did Peter have access to the Finance share on 15 April?"
Result: for every audit finding, an IAM engineer must manually reconstruct what the world-state was. With 100+ findings per audit cycle, that costs tens of hours. Under DORA and NIS2, the auditor needs the answer in minutes — not next Tuesday.
Every reconciliation run stores the following structure per grant. This is stored as JSONB in the reconciliation_run.per_grant_snapshots column, indexed on (identity_id, run_id, triggered_at):
{
"grant_id": "...",
"entitlement_name": "Finance Read-Only Share",
"is_in_sol": true,
"is_in_ist": true,
"sol_sources": [
{
"kind": "policy_derived",
"source_ref": "policy:baseline-employees",
"policy_name": "Baseline policy — all employees",
"granted_at": "2026-04-01T08:14:00Z",
"justification": "Department-baseline"
},
{
"kind": "role_inheritance",
"source_ref": "role:finance-employee",
"parent_entitlement_name": "Finance Role"
}
],
"assignment_kind": "MEMBER",
"valid_from": "2026-04-01T08:14:00Z",
"valid_to": null,
"last_used_at": "2026-04-15T13:22:00Z",
"usage_count_90d": 47,
"state": "aligned",
"reason": "SOL and IST confirmed — granted via policy_derived, role_inheritance.",
"computed_at": "2026-04-15T03:00:00Z"
}
// On drift, two additional fields are populated:
// "unapproved_action": what policy says should happen on this system
// "action_taken": what the engine actually did
One query on reconciliation_run.per_grant_snapshots returns the full state including the policy version active at that time (via sol_sources.source_ref + policy history).
Question: "How many evidence packages can we deliver instead of manual decisions?"
Answer: all of them. Audit evidence packs are one CSV export away.
Pull all snapshots for a period → review package ready for auditor. No manual reconstruction.
"Who had access to X at the moment of the incident?" → snapshot lookup answers in seconds, not days.
Compare snapshots before and after a role-model change → see exactly what changed per identity.
Weekly recon-runs produce a continuous evidence stream — always queryable, never reconstructed.
A typical tenant of 5,000 identities × 25 grants average = 125k grants. Per run: 125k snapshots × ~800 bytes = ~100 MB per run. At weekly runs × 52 weeks = ~5 GB/year in PostgreSQL JSONB.
Storage strategy: run snapshots in JSONB column with GIN index on (identity_id, run_id). Auto-prune after 7 years (DORA retention). Bulk-runs cap at 50 grants/identity to bound JSONB size; single-identity runs store everything. Query performance: typical audit query ("snapshots for identity X in the last year") returns in <50ms due to index on triggered_at.
| Framework | Reconciliation evidence addresses |
|---|---|
| DORA Art. 9 | "Maintain mapping between users and access rights" — per-grant snapshots provide point-in-time proof |
| NIS2 Art. 21 | "Identify and treat access anomalies" — drift detection with audit trail per anomaly |
| SOX 404 (ITGC) | "Access change tracking with before/after evidence" — SOL/IST at each run = before/after |
| GDPR Art. 32 | "Demonstrable measures for confidentiality" — access justification per grant, exportable |
| ISO 27001 A.9 | "Periodic access reviews with evidence" — recon runs are the evidence, not certificates of completion |
Reconciliation engine logic (reconciliation/engine.py):
The engine is pause-able via the global kill-switch — useful when performing a role-model migration without the provisioning flow running through your changes.
Reconciliation must not just detect — it must prove. By storing per-grant snapshots with reasons and sol_sources, you transform reconciliation from an ops tool into a compliance asset.
Continuous evidence, at individual-grant level, available for every audit question, for every identity, at every point in time. That's the difference between a compliance report and compliance evidence.