Understand the lifecycle of the events that occur in Directory Sync.
Directory Sync events represent actions performed within directory providers. For example, an action could mean an IT admin assigning a user to your app or modifying a user group assigned to your app. These actions form the basis of user lifecycle management (ULM).
WorkOS provides information about these actions through a set of structured events. This reference guide will cover the events Directory Sync produces and what they mean. To learn about how to handle these events on your side, see the data syncing guide.
This event occurs when you or your customer have successfully created a connection between WorkOS and your customer’s directory provider.
{ "event": "dsync.activated", "id": "event_01FKJ843CVE8F7BXQSPFH0M53V", "data": { "object": "directory", "external_key": "UWuccu6o1E0GqkYs", "name": "Foo Corp's Directory", "organization_id": "org_01EZTR6WYX1A0DSE2CYMGXQ24Y", "id": "directory_01EHWNC0FCBHZ3BJ7EGKYXK0E6", "state": "active", "type": "generic scim v2.0", "created_at": "2021-06-25T19:07:33.155Z", "updated_at": "2021-06-25T19:07:33.155Z", "domains": [ { "object": "organization_domain", "id": "org_domain_01EZTR5N6Y9RQKHK2E9F31KZX6", "domain": "foo-corp.com" } ] }, "created_at": "2021-06-25T19:07:33.155Z" }
dsync.activated
is triggered if you manually create the directory connection in the Developer Dashboard
The directory ID identifies a connection with the directory of a particular customer. Your app should save it and associate the directory ID with the corresponding organization ID.
This event occurs when a Directory Sync connection is deleted in WorkOS, thus tearing down the link between your customer’s directory provider and your app.
{ "event": "dsync.deleted", "id": "event_03FKJ843CVE8F7BXQSPFH0M53V", "data": { "object": "directory", "id": "directory_01EHWNC0FCBHZ3BJ7EGKYXK0E6", "organization_id": "org_01EZTR6WYX1A0DSE2CYMGXQ24Y", "type": "generic scim v2.0", "state": "deleting", "name": "Foo Corp's Directory", "created_at": "2021-06-25T19:07:33.155Z", "updated_at": "2021-06-25T19:07:33.155Z" }, "created_at": "2021-06-25T19:07:33.155Z" }
A connection can be deleted through the Admin Portal, Developer Dashboard
When receiving a dsync.deleted
event, you can ignore the connection’s state
attribute, since it indicates the state before the deletion occurs. When a directory is deleted in WorkOS, a sole dsync.deleted
event is sent.
When a dsync.deleted
event is received, it indicates that the users and groups in that directory have been deleted in WorkOS. You can process the dsync.deleted
event accordingly in your application, removing the organization’s groups and its users from your application or marking them as deleted. dsync.user.deleted
and dsync.group.deleted
events will not be sent for the deleted directory.
This event occurs when an IT admin creates a user using their directory provider. It is standard to create and provision the user in your app when you receive this event.
{ "event": "dsync.user.created", "id": "event_07FKJ843CVE8F7BXQSPFH0M53V", "data": { "id": "directory_user_01E1X1B89NH8Z3SDFJR4H7RGX7", "directory_id": "directory_01ECAZ4NV9QMV47GW873HDCX74", "organization_id": "org_01EZTR6WYX1A0DSE2CYMGXQ24Y", "idp_id": "8931", "emails": [ { "primary": true, "type": "work", "value": "lela.block@example.com" } ], "first_name": "Lela", "last_name": "Block", "job_title": "Software Engineer", "username": "lela.block@example.com", "state": "active", "created_at": "2021-06-25T19:07:33.155Z", "updated_at": "2021-06-25T19:07:33.155Z", "custom_attributes": { "department": "Engineering" }, "role": { "slug": "member" }, "raw_attributes": {} }, "created_at": "2021-06-25T19:07:33.155Z" }
You can add this user to your users table in your app and associate them with the directory ID and organization ID. You can begin to engage with the user at this point, e.g., send the user a “Getting Started” email.
During the initial sync of any directory, you will receive a dsync.user.created
event for each existing user in the directory.
This event occurs when users’ attributes change. These attributes may be standard attributes, auto-mapped attributes, or custom-mapped attributes.
{ "event": "dsync.user.updated", "id": "event_08FKJ843CVE8F7BXQSPFH0M53V", "data": { "id": "directory_user_01E1X1B89NH8Z3SDFJR4H7RGX7", "directory_id": "directory_01ECAZ4NV9QMV47GW873HDCX74", "organization_id": "org_01EZTR6WYX1A0DSE2CYMGXQ24Y", "idp_id": "8931", "emails": [ { "primary": true, "type": "work", "value": "lela.block@example.com" } ], "first_name": "Lela", "last_name": "Block", "job_title": "Software Engineer", "username": "lela.block@example.com", "state": "active", "created_at": "2021-06-25T19:07:33.155Z", "updated_at": "2021-06-25T19:07:33.155Z", "custom_attributes": { "department": "Engineering" }, "role": { "slug": "member" }, "raw_attributes": {}, "previous_attributes": {} }, "created_at": "2021-06-25T19:07:33.155Z" }
The payload for dsync.user.updated
event shows changes between directory group snapshots in the previous_attributes
property.
The changes in the object are shallow differences for root properties, raw_attributes
, and custom_attributes
. If the current snapshot has a new attribute that did not exist previously, then the value for the attribute will be indicated as null
.
This event occurs when a user is hard-deleted from a directory. Typically, you would remove the user from your app in this case.
{ "event": "dsync.user.deleted", "id": "event_09FKJ843CVE8F7BXQSPFH0M53V", "data": { "id": "directory_user_01E1X1B89NH8Z3SDFJR4H7RGX7", "directory_id": "directory_01ECAZ4NV9QMV47GW873HDCX74", "organization_id": "org_01EZTR6WYX1A0DSE2CYMGXQ24Y", "idp_id": "8931", "emails": [ { "primary": true, "type": "work", "value": "lela.block@example.com" } ], "first_name": "Lela", "last_name": "Block", "job_title": "Software Engineer", "username": "lela.block@example.com", "state": "inactive", "created_at": "2021-06-25T19:07:33.155Z", "updated_at": "2021-06-25T19:07:33.155Z", "custom_attributes": { "department": "Engineering" }, "role": { "slug": "member" }, "raw_attributes": {} }, "created_at": "2021-06-25T19:07:33.155Z" }
When users are removed from a directory, most providers will use a form of soft user deletion. In these cases, rather than receiving a dsync.user.deleted
event, you will receive a dsync.user.updated
event with the user’s state
marked as inactive
.
After Oct. 19, 2023, all new environments will delete Directory Users that get moved to the “inactive” state. If you would like to retain these users, please reach out to support. You can find more details here.
This event occurs when creating a directory group in the directory provider. WorkOS also sends this event when a directory connection is established.
{ "event": "dsync.group.created", "id": "event_44FKJ843CVE8F7BXQSPFH0M53V", "data": { "id": "directory_group_01E1X5GPMMXF4T1DCERMVEEPVW", "idp_id": "02grqrue4294w24", "directory_id": "directory_01ECAZ4NV9QMV47GW873HDCX74", "organization_id": "org_01EZTR6WYX1A0DSE2CYMGXQ24Y", "name": "Developers", "created_at": "2021-06-25T19:07:33.155Z", "updated_at": "2021-06-25T19:07:33.155Z", "raw_attributes": {} }, "created_at": "2021-06-25T19:07:33.155Z" }
When WorkOS ingests this event, it first processes the users in the group. So, in most cases, you would receive dsync.user.created
, then dsync.group.created
, and finally, dsync.group.user_added
.
For more information on best practices for out-of-sequence events, see the data syncing guide.
This event is sent when an attribute of a directory group has changed.
{ "event": "dsync.group.updated", "id": "event_54FKJ843CVE8F7BXQSPFH0M53V", "data": { "id": "directory_group_01E1X5GPMMXF4T1DCERMVEEPVW", "idp_id": "02grqrue4294w24", "directory_id": "directory_01ECAZ4NV9QMV47GW873HDCX74", "organization_id": "org_01EZTR6WYX1A0DSE2CYMGXQ24Y", "name": "Developers", "created_at": "2021-06-25T19:07:33.155Z", "updated_at": "2021-06-25T19:07:33.155Z", "raw_attributes": {}, "previous_attributes": {} }, "created_at": "2021-06-25T19:07:33.155Z" }
The payload for dsync.group.updated
events shows changes between directory group snapshots in the previous_attributes
property.
The changes in the object are shallow differences for root properties, raw_attributes
, and custom_attributes
. If the current snapshot has a new attribute that did not exist previously, then the value for the attribute will be indicated as null
.
This event occurs when deleting a directory group in the directory provider.
When a dsync.group.deleted
event is received, it indicates that the members in that group have been deleted in WorkOS. You can process the dsync.group.deleted
event accordingly in your application, removing the group’s members from your application or marking them as deleted. dsync.group.user_removed
events will not be sent for the members in the deleted group.
{ "event": "dsync.group.deleted", "id": "event_06FKJ843CVE8F7BXQSPFH0M53V", "data": { "id": "directory_group_01E1X5GPMMXF4T1DCERMVEEPVW", "idp_id": "02grqrue4294w24", "directory_id": "directory_01ECAZ4NV9QMV47GW873HDCX74", "organization_id": "org_01EZTR6WYX1A0DSE2CYMGXQ24Y", "name": "Developers", "created_at": "2021-06-25T19:07:33.155Z", "updated_at": "2021-06-25T19:07:33.155Z", "raw_attributes": {} }, "created_at": "2021-06-25T19:07:33.155Z" }
If your app relies on groups to sync users or map roles, you should remove access for the users who belonged to the deleted group.
This event occurs when adding a directory user to a directory group.
{ "event": "dsync.group.user_added", "id": "event_04FKJ843CVE8F7BXQSPFH0M53V", "data": { "directory_id": "directory_01ECAZ4NV9QMV47GW873HDCX74", "user": { "id": "directory_user_01E1X56GH84T3FB41SD6PZGDBX", "directory_id": "directory_01ECAZ4NV9QMV47GW873HDCX74", "organization_id": "org_01EZTR6WYX1A0DSE2CYMGXQ24Y", "idp_id": "2936", "emails": [ { "primary": true, "type": "work", "value": "eric@example.com" } ], "first_name": "Eric", "last_name": "Schneider", "job_title": "Software Engineer", "username": "eric@example.com", "state": "active", "created_at": "2021-06-25T19:07:33.155Z", "updated_at": "2021-06-25T19:07:33.155Z", "custom_attributes": { "department": "Engineering" }, "role": { "slug": "member" }, "raw_attributes": {} }, "group": { "id": "directory_group_01E1X5GPMMXF4T1DCERMVEEPVW", "idp_id": "02grqrue4294w24", "directory_id": "directory_01ECAZ4NV9QMV47GW873HDCX74", "organization_id": "org_01EZTR6WYX1A0DSE2CYMGXQ24Y", "name": "Developers", "created_at": "2021-06-25T19:07:33.155Z", "updated_at": "2021-06-25T19:07:33.155Z", "raw_attributes": {} } }, "created_at": "2021-06-25T19:07:33.155Z" }
If you map roles using groups, you should assign the group’s role to the newly added user.
This event occurs when removing a directory user from a directory group.
{ "event": "dsync.group.user_removed", "id": "event_05FKJ843CVE8F7BXQSPFH0M53V", "data": { "directory_id": "directory_01ECAZ4NV9QMV47GW873HDCX74", "user": { "id": "directory_user_01E1X56GH84T3FB41SD6PZGDBX", "directory_id": "directory_01ECAZ4NV9QMV47GW873HDCX74", "organization_id": "org_01EZTR6WYX1A0DSE2CYMGXQ24Y", "idp_id": "2936", "emails": [ { "primary": true, "type": "work", "value": "eric@example.com" } ], "first_name": "Eric", "last_name": "Schneider", "job_title": "Software Engineer", "username": "eric@example.com", "state": "active", "created_at": "2021-06-25T19:07:33.155Z", "updated_at": "2021-06-25T19:07:33.155Z", "custom_attributes": { "department": "Engineering" }, "role": { "slug": "member" }, "raw_attributes": {} }, "group": { "id": "directory_group_01E1X5GPMMXF4T1DCERMVEEPVW", "idp_id": "02grqrue4294w24", "directory_id": "directory_01ECAZ4NV9QMV47GW873HDCX74", "organization_id": "org_01EZTR6WYX1A0DSE2CYMGXQ24Y", "name": "Developers", "created_at": "2021-06-25T19:07:33.155Z", "updated_at": "2021-06-25T19:07:33.155Z", "raw_attributes": {} } }, "created_at": "2021-06-25T19:07:33.155Z" }
If you map roles using groups, you should remove the group’s role from the user who belonged to the group.
The WorkOS API allows for data reconciliation for your app. You can use the WorkOS API to pull the latest data to reconcile any data discrepancies between WorkOS and your app.
A standard method apps use for data reconciliation is to set up a cron job that pulls from the WorkOS API on a consistent interval, e.g., every 1 to 6 hours, depending on your app’s user provisioning volume.
Known issue: Keeping track of WorkOS updated timestamps is of limited use right now because group membership changes for users do not alter the WorkOS updated_at
timestamp. We’re actively working on this issue.
The general approach for performing a full sync of Directory Sync objects goes as follows:
You can also reconcile directory data using the events API. See our data syncing guide to learn more.