Directory Provisioning
Create and manage AuthKit users and organization memberships from your customers' directories, with roles applied from directory group mappings.
Directory Provisioning is enabled by WorkOS support for your whole WorkOS team. It cannot be enabled for individual organizations or directories. To request it, contact support@workos.com or your team’s WorkOS Slack channel. Read Enable Directory Provisioning first: directories that already exist when it is enabled are not affected.
This page covers provisioning your application’s users and organization memberships from your customers’ directories. To provision members of your own WorkOS dashboard team from your identity provider, see dashboard directory provisioning.
Directory Provisioning is the AuthKit feature that creates and maintains an AuthKit user and organization membership for every user in an organization’s directory. The IT admin manages access from their identity provider. Domain-managed users, whose email domain matches one of the organization’s verified domains, are added as active members without an invitation. Domain guest users, whose email domain is not verified, are invited to the organization. In both cases their directory group role assignments are applied to the membership.
Directory Provisioning builds on Directory Sync. Directory Sync alone does not create AuthKit users. If your application uses Directory Sync without AuthKit, this page does not apply; the Directory Sync documentation covers the directory user and group objects you work with.
Directory Sync produces directory objects: a directory, its directory users, its directory groups, and the dsync.* events that describe changes to them. A directory user records that the IT admin has assigned a person to your application. It is not an AuthKit user, and it cannot sign in.
Without Directory Provisioning:
- Synced users appear on the directory’s Users tab in the WorkOS dashboard but not on the organization’s Users tab, because no AuthKit user or organization membership is created.
- A directory group role assignment sets the
roleandrolesfields on the directory user only. No organization membership receives the role, so theroleandpermissionsclaims in the access token do not change. The membership keeps whatever role it already has: the default role, unless SSO role assignment or your application set another. - Deprovisioning a user in the directory changes the directory user’s
stateand emitsdsync.user.updatedordsync.user.deleted. No organization membership is deactivated and no session is revoked. directory_managedisfalseon every organization membership.
With Directory Provisioning, each directory user is linked to an AuthKit user and an organization membership in the directory’s organization. The membership has directory_managed: true, its roles follow the directory group role assignments, and deprovisioning deactivates it. The directory provisioning actions table lists every change.
| Outcome | Directory Sync alone | With Directory Provisioning |
|---|---|---|
| AuthKit user created for each directory user | No | Yes |
| Organization membership created | No | Yes, with directory_managed: true |
| Directory group role assignment reaches | The directory user’s role and roles |
The organization membership and the access token claims |
| Deprovisioning in the directory | Updates the directory user | Deactivates the membership and revokes the user’s sessions |
| Directory groups mirrored into AuthKit groups | No | Not currently |
If your application uses AuthKit, enable Directory Provisioning. If it already creates AuthKit users from dsync.* events, stop that job first; see Before you request it. If it doesn’t use AuthKit, use Directory Sync alone.
Consider Acme, a SaaS company on AuthKit. A customer connects Okta with SCIM and maps the “Engineering” group to Acme’s developer role. Without Directory Provisioning, Acme sees 40 directory users with "role": {"slug": "developer"}, but the organization has no members, and an engineer who signs in with SSO and has no other role assignment gets the default member role. With Directory Provisioning enabled before the directory was created, the same sync creates 40 users and 40 active memberships with the developer role, and each engineer’s first access token carries "role": "developer".
WorkOS support turns Directory Provisioning on for your whole WorkOS team: every environment in every project, including environments created later. Staging and production then provision directories the same way, so your application needs only one code path. It can’t be enabled per organization or per directory.
Directory Provisioning applies only to directories created after it is enabled. A directory that already exists keeps standalone behavior: its users stay unlinked and directory_managed stays false on their memberships. To bring an existing directory under Directory Provisioning, delete it (in the WorkOS dashboard, through the Admin Portal, or with DELETE /directories/{id}) and have the IT admin set it up again. Deleting a directory does not deactivate or delete organization memberships, so users keep signing in during the change.
When the replacement directory completes its initial sync, WorkOS matches each directory user to an existing membership in the organization, primarily by email address, links the membership in place, applies the mapped role, and emits organization_membership.updated. Directory users with no matching membership, including users whose directory email differs from the email on their existing membership, are provisioned as new users and memberships. For example, if 129 of a directory’s 275 users match existing members by email, the first sync links those 129 memberships and creates 146 new ones. Existing members who are not in the directory are left as they are and do not reduce that count.
- Directory groups are not currently mirrored into AuthKit groups. Group-to-role mappings still apply to the membership. If your application needs raw group membership, keep reading it from the Directory Sync API and
dsync.group.*events, which continue unchanged. If you’d like directory groups mirrored into AuthKit groups, contact support@workos.com to register your interest. - Users whose email is outside the organization’s verified domains receive an invitation email by default. To stop that, disable invitation emails for the environment. The setting also covers invitations you send yourself.
- If your application already creates AuthKit users from
dsync.*events, stop that job before enabling. Two writers acting on the same directory changes produce conflicting memberships. - Turning Directory Provisioning off later requires contacting WorkOS support. Test it in a sandbox environment first.
After a directory syncs, list the organization’s memberships with GET /user_management/organization_memberships?organization_id=org_.... Linked memberships have directory_managed: true. organization_membership.created and organization_membership.updated events appear on the events page. A user’s roles appear in the access token the next time one is issued; tokens already issued keep their claims until they expire.
A Directory Sync integration is required for every organization that sources users and memberships through Directory Provisioning. Directories can be set up in the WorkOS Dashboard with Setup Links. You can also integrate the Admin Portal with your app to generate links to configure directories.
Directory Provisioning is supported for all SCIM directory providers, Google Workspace, and SFTP.
Users provisioned through a directory with an email domain matching a verified organization domain are added as active members of the organization, without an invitation.
Other users are created with pending memberships and receive an email invitation to join the organization. Pending members cannot sign in until the invitation is accepted, at which point they become active organization members.
In addition to provisioning new users, updates to existing users and deprovisioning events are reflected in AuthKit.
Users with email addresses matching one of the organization’s verified domains are fully managed by the directory. Updates to their attributes from the directory override changes made through SSO, the API, or manually in the dashboard.
Other users, with email domains not verified by the organization, are not fully managed by the directory, so updates made via SSO, API, or manually in the dashboard persist.
When a user is deprovisioned in the directory, the status of their corresponding organization membership is set to inactive. The user can no longer sign in to the organization, but the membership and user are not deleted.
If a user is re-provisioned in the directory, their organization membership is reactivated with its previous role and its status is set to active.
With Directory Provisioning, custom attributes configured on directory users are available on the corresponding organization membership. This gives you IdP-sourced attributes like department, job title, and cost center directly from the membership object or in JWT templates.
When a directory user’s attributes are updated, the changes are reflected on the linked organization membership’s custom_attributes.
The table lists directory provisioning and deprovisioning actions and the corresponding changes triggered in AuthKit. If you’re using standalone Directory Sync, refer to the standalone Directory Sync documentation.
Actions depend on the user’s email domain:
- A user is domain-managed when their email domain matches one of the organization’s verified domains. These users are fully managed by the directory.
- A user is a domain guest when their email domain does not match one of the organization’s verified domains. Changes only impact the linked organization membership.
| Directory Action | Changes triggered in WorkOS | Event(s) Emitted |
|---|---|---|
| Directory user provisioned | User and organization membership objects created. Domain-managed users are created with an active status, while domain guest users are invited to the organization with a pending status. | user.created, organization_membership.created |
| Directory user info updated | For domain-managed users, any updates to the user’s name will be reflected on the user object. Email updates are reflected only when the directory has user-level authority over the user; see email changes for details. The user’s organization membership role will be re-synced to match the IdP role assignment. | user.updated, organization_membership.updated |
| Directory user with active membership deprovisioned | Organization membership deactivated and all sessions for the user are revoked. Their role is reset to the default role. | organization_membership.updated |
| Directory user with pending membership deprovisioned | Organization membership deleted. | organization_membership.deleted |
| Directory user reactivated | Organization membership reactivated. | organization_membership.updated |
To keep your application in sync with Directory Provisioning, listen for the AuthKit user.* and organization_membership.* events in the table. You don’t need to handle dsync.user.* events to track provisioned users and memberships.
Users appear under the directory’s Users tab but not under the organization’s Users tab. Do I need Directory Provisioning?
Yes. Directory Sync alone creates directory users, which are not AuthKit users. Have Directory Provisioning enabled before the directory is created, or delete and recreate the directory after it is enabled.
My group-to-role mapping shows on the directory user but not on the organization membership or in the JWT. Why?
Because nothing links the directory user to a membership. Without Directory Provisioning, the mapped role stops at the directory user’s role and roles fields. The access token’s role and permissions claims come from the organization membership, which keeps its existing role: the default role, unless SSO role assignment or your application set another. Enable Directory Provisioning and recreate the directory, or set the role on the membership yourself with role_slug.
Can Directory Provisioning be enabled only for specific organizations?
No. It is enabled for your whole WorkOS team, so every organization is provisioned the same way.
What happens to my existing directories when Directory Provisioning is enabled?
Nothing. Only directories created after it is enabled are provisioned. Delete each existing directory and have the IT admin set it up again; existing memberships with the same email address are matched and linked on the first sync, and none are deactivated by the deletion.
I am using directory provisioning, but some directory users aren’t being provisioned in AuthKit. Why would a directory user not be provisioned in AuthKit?
Directory users need to have a primary email address to be provisioned in AuthKit. If the directory user is missing a primary email, they won’t be provisioned. Additionally, if the primary email of a directory user is shared by another directory user, only one will be provisioned in AuthKit, as emails are unique to AuthKit users.
If a user’s email is changed in the directory, will this change be reflected on the user’s email in WorkOS?
The email change propagates to the User object when the directory has user-level authority over the user – the user’s current email domain is managed by the organization’s domain policy – and the new email is on one of the organization’s verified domains. If the new email already belongs to another user, the change is skipped. See email changes for the full set of rules and precedence.
If two organizations share a verified domain, which one manages the AuthKit user?
The first organization to provision a user through directory sync claims that user, and its directory manages the user’s name and email. If another organization later provisions the same user, it does not take over management by default. Ownership only transfers to a different organization when that organization has domain capture enabled for the email domain. See email changes for details.
Why is there a distinction between domain-managed users and domain guest users?
For domain-managed users, the organization has proven they own the email domain through domain verification, and therefore have full control over the user’s account and email. This allows the directory to manage all aspects of the user object.
For domain guests, the organization has not proven ownership of the user’s email domain. As a result, the organization only has the ability to manage data within the scope of the organization itself, represented by the organization membership object.
Why aren’t organization memberships deactivated when a directory is deleted?
User deprovisioning and directory deletion have different behaviors because they serve different use cases. Deactivating all users is typically an off-boarding task that affects the entire organization, not just the directory. By leaving memberships active when a directory is deleted, customers can switch directory providers without the disruption of deactivating all memberships.
Deleting a directory removes the directory, its directory users, and its directory groups, but it does not deprovision the AuthKit users or organization memberships it created. Their organization memberships stay active, roles assigned from directory group mappings remain on the memberships, existing sessions and refresh tokens are not revoked, and no organization_membership events are emitted.
To remove access for synced users, deprovision them in the identity provider and let the change sync before deleting the directory. Deprovisioning deactivates each user’s active membership, deletes pending ones, and revokes the user’s sessions. Alternatively, after deleting the directory, deactivate active memberships or delete pending ones.