> For the complete documentation index, see [llms.txt](https://docs.aohwv.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.aohwv.dev/trust-security-and-data-handling/identity-dataplane.md).

# The Identity Dataplane

AOH Sync's identity model is the authoritative record of who exists across your connected systems. This page describes precisely how AOH Sync represents identity data, how it resolves conflicts when the same attribute appears in multiple sources, and how normalized identity data flows to Microsoft Entra ID.

***

## Core concept: the Identity aggregate

An **Identity** is the top-level object that represents a real person (or a non-human principal) across all the systems you have connected to AOH Sync. A single Identity can have many constituent parts because most enterprise environments spread identity data across multiple systems. For example, a person might exist as a `User` record pulled from your HR system, one or more `Account` records in your directories or SaaS tools, and one or more `Machine Identity` records if they own service accounts or shared mailboxes.

The four component types that an Identity aggregates are:

| Component              | What it represents                                                                                                                                                                                                                                                 |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **User**               | The person record as read from a Source System. Carries core profile data: `user_principal_name`, `display_name`, `email`, `job_title`, `status`, `hire_date`, roles, groups, and department memberships.                                                          |
| **Account**            | A directory or application account that belongs to the identity. An Account is linked back to the Identity via a `person_id` reference and carries its own `identifier`, `status`, and `source_system_id`.                                                         |
| **Machine Identity**   | A non-human principal (service account, shared mailbox, robot user) that is owned by or associated with this identity. Machine Identities carry a `classification`, an `owned_by` reference, a `manager_id`, a `technical_inheritor`, and a computed `risk_score`. |
| **Identity Attribute** | A single resolved key-value pair — for example, `job_title = "Senior Engineer"` — with full provenance metadata describing where the value came from and which source wins when there is a conflict.                                                               |

The Identity object itself carries `id`, `display_name`, `status`, `created_at`, and `updated_at` timestamps, plus the four arrays above.

***

## Attribute conflict resolution: source, priority, and provenance

When you connect multiple Source Systems to AOH Sync, the same attribute (e.g., `job_title` or `department`) may arrive from more than one source with different values. AOH Sync resolves conflicts through the **IdentityAttribute** model, which attaches provenance metadata to every resolved attribute value.

Each IdentityAttribute record carries:

| Field         | Purpose                                                                                                                            |
| ------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `field_name`  | The attribute being resolved (e.g., `job_title`).                                                                                  |
| `field_value` | The winning value after conflict resolution.                                                                                       |
| `source_type` | The category of system the value came from (e.g., your HR connector, a directory connector).                                       |
| `source_id`   | The specific Source System instance that supplied this value.                                                                      |
| `priority`    | An integer that determines precedence when multiple sources supply the same `field_name`. Lower numbers indicate higher authority. |
| `updated_at`  | When this attribute value was last written, for audit trail purposes.                                                              |

When two sources supply the same `field_name`, AOH Sync retains the value from the source with the **lowest priority number** (highest authority). The losing value is not stored — only the winning value and its provenance are persisted. This means every attribute you see in AOH Sync is traceable back to the exact Source System that supplied it.

***

## Graph model: how entities relate

AOH Sync stores the identity graph in a property graph database (Neo4j), where nodes represent identity entities and directed edges represent relationships. The key relationships are:

```
Source --[USER_OF]--> User
Source --[SOURCE_OF]--> Group
Source --[DEPARTMENT_OF]--> Department
User --[MEMBER_OF]--> Group
User --[WORKS_IN]--> Department
User --[CAUSED]--> IdentityLifecycleEvent
Department --[CONTAINS]--> Group
IdentityLifecycleEvent --[NEXT]--> IdentityLifecycleEvent
```

Membership edges carry `from` and `until` timestamps, so AOH Sync maintains a temporally accurate record of when a user joined or left a group or department — useful for access-review and audit purposes.

Identity lifecycle events (joiner, mover, leaver) are linked both to the User that caused them and to each other in a time-ordered chain via the `NEXT` relationship, making it possible to reconstruct the full history of any identity's lifecycle transitions.

***

## Data flow: source to Entra

The path from a raw record in your Source System to a provisioned object in Microsoft Entra ID passes through three stages:

```
                                        Conflict
Source Systems           Normalization  Resolution     Target (Entra)
--------------------------------------------------------------------
                                        +-----------+
HR System ──────────┐                  |           |
                    │   +-----------+  | Identity  |  SCIM Bulk
Azure AD (source) ──┼──>| Ingest &  |->| Attribute |->Upload ──> Entra ID
                    │   | Normalize |  | Priority  |
SQL / REST ─────────┘   +-----------+  | Merge     |
                                        +-----------+
                            Neo4j          Redis           Graph API
                         Identity Graph    Cache
```

**Stage 1 — Ingest and normalize.** Connectors pull records from Source Systems (Microsoft Graph delta queries, SQL databases, REST endpoints, SFTP/CSV files). Raw records are converted to the AOH Sync domain model (User, Group, Department objects), deduplicated, and written into the identity graph.

**Stage 2 — Conflict resolution.** When the same identity appears in multiple sources, the IdentityAttribute priority model determines the authoritative value for each field. The resolved Identity object — with its Users, Accounts, Machine Identities, and winning Attributes — becomes the canonical record.

**Stage 3 — Provision to Entra.** The canonical identity data is formatted as SCIM Bulk Upload operations and sent to Microsoft Entra ID via the Microsoft Graph API. Attribute mappings (which you configure per Entra target) control exactly which normalized fields are written to which Entra attributes.

***

## Lifecycle events

AOH Sync tracks three lifecycle event types for every identity:

| Event type | Meaning                                                                       |
| ---------- | ----------------------------------------------------------------------------- |
| `joiner`   | A new identity has appeared in at least one Source System.                    |
| `mover`    | An attribute that signals a role or department change has been updated.       |
| `leaver`   | The identity has been deprovisioned or disabled across its connected sources. |

These events are stored in both the identity graph (for graph-traversal queries) and a relational store (for efficient time-range queries and audit export). Each event carries a structured `details` payload and a timestamp.

***

## Related

* [What Data AOH Sync Stores](/trust-security-and-data-handling/what-data-we-store.md)
* [Where Your Data Lives](/trust-security-and-data-handling/data-residency.md)
* [Encryption](/trust-security-and-data-handling/encryption.md)
* [Microsoft Entra Permissions Requested](/trust-security-and-data-handling/entra-permissions.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.aohwv.dev/trust-security-and-data-handling/identity-dataplane.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
