Skip to main content
Two failure modes in any authorization store are silent by nature: a directory sync that only ever adds (so offboarding never propagates), and grant rows referencing identifiers the host application deleted (so a reused id resurrects dead access). Alfiz 0.7.0 gives both a first-class answer.

Authoritative directory import

importDirectory is upsert-only by default. That is safe for partial snapshots and exactly wrong for offboarding: a user who disappears from the directory keeps active: true, their memberships, and their reporting edge until someone notices. { authoritative: true } makes the snapshot the truth of every dataset it carries:
Per dataset, precisely: Datasets the snapshot omits are untouched in either mode, groups are never deleted here (a vanished directory group may still be referenced by grants, and that finding belongs to the reconciliation below), and every deprovisioning action is audited with its reason. Wire your SCIM endpoint or HRIS export to produce a DirectorySnapshot and run authoritative imports on a schedule; the warnings array is your sync-health signal, and a growing deactivatedUsers count with an empty directory diff is the classic sign the mapping broke.

Row reconciliation

Grants and revokes reference subjects and scopes as opaque strings, by design, since your users and resources live in your tables. The database therefore offers no referential backstop. The documented discipline is calling deleteSubject / deleteScope / notifyScopeMoved alongside your own deletions and moves; reconcileRows is the detection that discipline used to lack:
You supply existence predicates over your tables; group- and role-referencing rows are checked against Alfiz’s own storage with no callback. Predicates you omit are simply not checked. Implicit subjects (directs:x, orgof:x) check the user behind them. Detection is write-free, so run it nightly and alert on non-empty. Then sweep deliberately:
Sweeping deletes orphans through the same audited paths as any other removal, emits the invalidation events, and records a summary entry. Two boundaries are deliberate. danglingRoleGrants are reported and never swept, because the row’s subject and scope are real and deleting it could mask a role-sync bug. And a sweep without provenance is rejected before anything is touched.
The sharp edge this exists for: grants key on id strings. If your host reuses identifiers (serial user ids, re-slugged resources), a stranded row is not garbage. It is live access waiting for the id to come back. Run detection before enabling reuse-prone id schemes, and keep deleteSubject in the offboarding path rather than relying on reconciliation to catch up.

How the three layers fit

  • The write-path discipline (deleteSubject, deleteScope, notifyScopeMoved) is the design: cleanup in the same code path as the deletion.
  • Authoritative sync keeps the organizational data (users, memberships, edges) true to the directory on a cadence.
  • Reconciliation is the backstop that finds what both missed, with a paper trail when it sweeps.