Skip to main content
SOX ITGC, SOC 2 (CC6.2/6.3), ISO 27001 (A.5.18), and PCI DSS 7.2.4 all expect periodic user access reviews. Alfiz does not ship review campaigns. Reviewer assignment, escalation, and attestation workflows are what your IGA (Entra ID Governance, Okta IGA, ConductorOne, Opal, Veza) or your ticketing system already does well. Alfiz ships the part only it can do: computed, attributable answers to what each person can actually do, and the reports that keep those answers true between cycles.

The entitlement export

Raw grant rows cannot be reviewed: between the group DAG, role indirection, implicit manager subjects, everyone, and revokes, effective access is a computation. exportEntitlements runs it per user:
What a reviewer reads: capability (held), not rows. What remediation uses: the sources. Each one names the grant row to revoke or end-date, and a personal revoke covers the “remove this one person from inherited access” case. Write-back is the ordinary API; there is no parallel remediation surface to integrate. Candidates default to every user the store can name (records plus user-subject grant rows); pass { userIds } for a population your host enumerates. Pair each export with the audit cursor for the evidence trail, and with listSodViolations for the conflicts page of the same review.

Wildcard drift: what changed since you certified

Forward-inclusive wildcards are a deliberate commitment: a stored docs.files.* grant absorbs keys published under that prefix later, with no write and no re-review trigger. A grant certified in Q1 may therefore confer permissions that did not exist in Q1. Since 0.7.0 every catalog publish retains its document, and the drift report makes the absorption visible:
The review loop: record the catalog version each cycle certifies; open the next cycle with listWildcardDrift({ sinceVersion }); every finding is a grant or assigned role now conferring more than what was signed. Expired grants and unassigned roles are excluded, since they confer nothing. removedKeys surfaces tombstone candidates in the other direction.
Drift needs catalog history. The bundled drivers retain it (the Prisma schema’s optional AlfizCatalogVersion model); a schema without the model answers unsupported rather than wrongly.

The IGA integration shape

  • Ingest: run exportEntitlements() on the IGA’s collection schedule and map userId + entitlements[].key (+ per-source scope) onto its entitlement model. The export is deterministic JSON; diffing two runs is the IGA’s incremental feed.
  • Certify: campaigns, reviewer routing, and attestations live in the IGA. Alfiz’s reporting hierarchy (getReportingEdges) can seed reviewer assignment.
  • Remediate: the IGA’s revoke decision calls your endpoint, which calls deleteGrant / createRevoke / an expiry update, audited like every write. A review that cannot remediate is not a control, and this one closes the loop with three ordinary calls.
  • Evidence: the audit export (cursor paging, optional hash chain) is the record that the remediation happened.

What is deliberately not built

First-party campaign objects, meaning population snapshots with reviewer state machines, would duplicate the half of IGA tooling that is workflow rather than authorization. The primitives above are the half that must come from the authorization layer because only it can compute them. If you operate no IGA, the export plus a spreadsheet and the audit trail is a defensible small-company review; the ingredients do not expire if you later adopt one.