Every identity governed.
Every entitlement proven.
Fulfillment isn't just provisioning. It's the governed lifecycle of every identity, every account, and every entitlement across every connected system — from onboarding through reconciliation to proof.
Batch-optimized provisioning. Continuous drift detection. Deterministic identity resolution. Dynamic group membership. Event-driven automation. All authorized by the same PDP, all recorded in the same proof chain.
The fulfillment gap
Most IGA platforms handle the request. Who handles what comes after? Provisioning that actually reaches the target system. Reconciliation that catches when reality drifts from policy. Proof that the right access was granted to the right person at the right time.
Provisioning black box
Access was approved. Was it actually provisioned? In the right system? With the right attributes? Most platforms don't know — they sent the request and hoped for the best.
Orphaned access
An employee left three months ago. Their Entra ID groups are still active. Nobody told the system, and the system never checked. This is a compliance finding that takes days to discover manually.
Identity chaos
john.smith@acme.com, jsmith, CN=John Smith — three identifiers for one person across three systems. Without deterministic resolution, you can't link accounts or enforce consistent policy.
Manual reconciliation
Every quarter, the IAM team exports access lists from each system, pastes them into spreadsheets, and compares them by hand. Three to five days. Every quarter. Auditors hate it.
Identity lifecycle: joiner, mover, leaver
Every identity starts with an anchor — a canonical identity_uuid that ties together accounts across every connected system. When a new account appears from a DataCollector sync, the onboarding pipeline resolves it: does this person already exist? Is this a new identity or a new account for an existing one?
Deterministic matching rules link accounts to identities automatically. When data is ambiguous — the same name appears in two departments — the conflict queue surfaces it for human review instead of guessing. No fuzzy matching. No confidence scores. Clean resolution or explicit escalation.
Identity anchor created. Accounts linked via matching rules. Birthright access provisioned. Neo4j graph projected with OWNS edges.
Department change detected via attribute flow. UEAS triggers mover reconciliation. Old access reviewed. New access provisioned. Dynamic groups recomputed.
Offboarding event triggers access revocation across all connected systems. Entitlement ledger records revocation with proof. Reconciliation verifies removal.
Technical deep-dive Identity resolution: deterministic matching and conflict handling
The Resolution Service
The Identity & Object Resolution Service bridges messy external identifiers (emails, usernames, group names) and EmpowerNow's canonical identity system (ARNs). It uses a two-tier strategy: Tier 1 is fast deterministic resolution — exact key match on identity_uuid, email, or employee ID. Tier 2 is AI-agent-assisted resolution for ambiguous cases, using the WAITING protocol to suspend execution until a human or AI agent resolves the conflict.
Matching Rules
Matching rules are declarative — they specify which transformed_data field to match on (email, employee_id, username), with support for composite rules (logic: all|any). Rules are scoped (global vs. system-specific) and support shadow mode for safe deployment: the rule evaluates and logs its decision but doesn't apply it until you promote to enforce mode.
Account Link State Machine
Each account-to-identity link has a state machine with valid transitions: pending → linked, pending → conflict, conflict → linked, linked → unlinked. Conflicts are surfaced in the admin UI with enriched candidate data — identity search profiles and account data side by side — so reviewers can make informed decisions.
Neo4j Graph Projection
Resolved identities and their account links are projected into Neo4j as Identity and Account nodes with OWNS edges. This is the identity graph substrate that powers attribute flow, dynamic groups, authorization decisions, and every other downstream service.
Batch-optimized provisioning
When an access campaign revokes 500 entitlements, EmpowerNow doesn't make 500 individual API calls. The batch fulfillment engine aggregates operations by target system, groups them by batch key, and executes them as single API calls — Graph $batch for Entra ID, SCIM PATCH for SAP IAS, LDAP connection batching for Active Directory.
95% throughput improvement. Fewer rate-limit errors. Atomic operations with automatic retry. Every batch job produces an execution receipt that flows into the proof chain.
Technical deep-dive Batch fulfillment internals: aggregation, execution, and receipts
Batch Key Aggregation
Individual fulfillment jobs are grouped by batch key: {tenant_id}:{system_instance_id}:{operation}:{resource_kind}:{target_id}. Jobs start in BATCH_PENDING status. The Batch Aggregator creates a parent batch job containing all children, then the Batch Worker executes a single API call containing all operations.
Semantic Modes
Two batch semantics: PER_ITEM (Entra ID, AD) — each operation in the batch can succeed or fail independently, and individual child jobs are updated accordingly. ALL_OR_NOTHING (SAP IAS SCIM) — the entire batch succeeds or fails as one unit.
Execution Receipts
Every batch execution produces a structured receipt: the batch key, child job IDs, the API call made, the response received, and the resulting status of each child job. This receipt flows into the proof chain alongside the authorization decision that permitted the fulfillment in the first place.
Continuous drift detection & reconciliation
Reconciliation continuously compares what access should exist (governance state) with what access actually exists (external system state) — and flags every discrepancy. Not once a quarter in a spreadsheet. Continuously, automatically, with structured remediation actions.
Access exists in the external system but has no approved directive. Access that shouldn't be there. Flagged for review or automatic revocation.
An approved directive exists but the access hasn't been provisioned in the external system. Access that should be there but isn't. Triggers re-provisioning.
Access exists and is approved, but attributes differ — wrong role level, wrong scope, wrong expiration. The access is present but incorrect.
Sync adapters collect current access state from each connected system. The reconciliation engine compares it against the Entitlement Ledger — the governed record of what access has been approved, by whom, and under what policy. Drift items appear in the Operations Manager with structured detail: the expected state, the actual state, and recommended remediation.
When configured for automatic remediation, the engine can resolve drift items directly — re-provisioning missing access or flagging orphans for revocation — with every remediation action flowing through the same AuthZEN authorization and proof chain as any other operation.
Data owner self-service
If you own an application — a SaaS product, an internal database, an LDAP directory, a legacy mainframe — EmpowerNow lets your end users discover, request, and manage access to your resources through a self-service catalog. No more email requests, no more spreadsheets, no more "who has access to what?" answered with a SQL query three days later.
Dynamic Group Engine
Static group membership doesn't scale. When someone changes departments, their Entra ID groups should update automatically — not after a ticket, not after a manual review, not next quarter. The Dynamic Group Engine (DGE) evaluates ABAC rules against identity attributes in real time and computes membership deltas: who should be added, who should be removed.
External Sync Policies define the rules: "All identities where department=Engineering AND location=Berlin belong to this Entra ID group." When any attribute changes, the DGE recomputes, emits AccessDirectives for fulfillment, and the batch engine provisions the changes. All changes flow through the proof chain.
Technical deep-dive DGE architecture: policies, computation, and external sync
External Sync Policies
Admins define ExternalSyncPolicy objects in the Membership Service (Neo4j). Each policy specifies: the target (an external group in Entra ID, SAP IAS, etc.), the ABAC rule (attribute conditions), and the sync behavior (add-only, full-sync, remove-only). Policies publish change events to Kafka.
Computation Engine
The DGE Service (port 8010) evaluates ABAC rules against identity attributes. When identity attributes change (department transfer, location update), the engine computes the delta: who should be added, who should be removed. Deltas are emitted as AccessDirectives to the fulfillment pipeline.
Resource Collections
Resource Collections are policy-driven groupings of resources for authorization scoping. The Resource Index Service materializes collection membership for PDP queries — so authorization decisions can reference dynamic sets ("all resources owned by the Finance team") rather than static lists.
Virtual Directory Server: legacy bridge
SAP GRC doesn't call REST APIs. It writes to LDAP. SAP IDM doesn't post webhooks. It opens LDAP connections and modifies groups. These systems won't change — they've been doing this for twenty years. So EmpowerNow speaks their language.
The Virtual Directory Server (VDS) is a Python service that speaks the LDAP protocol but isn't a real directory. It's a protocol bridge — it accepts LDAP connections from legacy systems, translates LDAP operations (BIND, MODIFY, ADD, DELETE) into structured events, and publishes them into the UEAS automation pipeline via Kafka. SAP GRC thinks it wrote to a directory. It actually triggered a governed automation workflow. Zero configuration changes on the GRC side.
LDAP MODIFY
"add member CN=jsmith"
Classify, normalize,
publish to Kafka
Policy evaluation,
suppression, intent
Authorized provisioning
with proof receipt
Event-driven automation (UEAS)
The Unified Event Automation System is the backbone that connects everything on this page. When SAP GRC approves a role request, UEAS provisions it. When an employee changes departments, UEAS triggers the mover workflow. When a compliance violation fires at 2 AM, UEAS wakes an AI agent to investigate immediately.
No code changes needed. You write a declarative JSON rule — "when this event happens, do that" — and the engine handles ingestion, deduplication, rule evaluation, suppression, reliable delivery, retry with backoff, dead-letter queuing, and full audit trail. Exactly-once semantics: all database writes happen in one transaction, Kafka offset commits happen after DB commit.
Create or revoke an entitlement in the ledger and fulfill it in the target system.
Start a multi-step governed workflow — mover reconciliation, access review, investigation.
Create a human review task in the Task Center for manager approval or investigation.
Execute a governed operation on a connected system — disable account, reset password, sync group.
Wake an autonomous AI agent to investigate, resolve, or escalate — within delegation governance.
Technical deep-dive UEAS pipeline: five phases, suppression, and exactly-once delivery
Five-Phase Pipeline
Ingest — Events arrive via webhook, polling, or VDS protocol bridge. Payloads are normalized into a canonical NormalizedEvent envelope. Deduplication prevents the same event from being processed twice. Normalize — The NormalizerService opens a database transaction, upserts correlation state (the subject's memory), and marks the event as processed. Evaluate — The PolicyEngine matches the event against declarative JSON rules. Matching rules emit intents. Publish — Allowed intents are written to a transactional outbox table, then reliably published to Kafka. Apply — The IntentApplierWorker consumes intents and executes them via HTTP to the target service, with idempotency keys and retry.
Suppression Engine
Not every matched event should fire an action. The SuppressionEngine throttles intents within configurable time windows — preventing duplicate provisioning if the same GRC ticket fires three webhook retries in five minutes. Suppression is per-subject, per-rule, with configurable cooldown periods.
Six Intent Types
ACCESS_DIRECTIVE (entitlement lifecycle), PLAYBOOK (multi-step workflow), REVIEW (human task), COMMAND (system operation), SENTINEL (AI agent), and EVENT_INTERACTION (future: agentic workflow mesh). Each intent type routes to a specific service endpoint with its own retry and dead-letter semantics.
Connected to the control plane
Fulfillment isn't a standalone silo. Every operation — provisioning, reconciliation, dynamic group sync — flows through the same control plane that governs every other EmpowerNow capability.
Every fulfillment action pre-flight authorized. Same PDP as UI and agent actions.
Authorization →Reference-counted assignments. Safe revocation. The governed record of who has what.
How It Works →Every provisioning action produces a cryptographic receipt. Every drift remediation is proven.
How It Works →Every connector action becomes a governed workflow step and MCP tool — automatically.
Connector & Tool Factory →Compliance drift detection as an agent capability. Filter, aggregate, export at scale.
ATU →See governed fulfillment on your systems
We run live demos against your actual environment — your Entra ID, your SAP IAS, your Active Directory. Watch batch provisioning, drift detection, and identity resolution in real time.