SCIM Directory Sync
SCIM directory sync.
SCIM (System for Cross-domain Identity Management) directory sync keeps your Rensei workspace automatically in sync with your identity provider. When a group is created, renamed, or deleted in Okta, Azure AD, or any WorkOS-connected directory, the corresponding Rensei teams update in real time. When a user is deprovisioned in your IdP, their Rensei access is revoked.
How directory sync works
The platform receives SCIM events via a dedicated webhook at POST /api/scim/webhook. Signature verification uses HMAC-SHA256 over the request body; the signing secret is configured by your Rensei deployment operator.
Supported events
| Event | Action |
|---|---|
dsync.group.created | Creates (or maps) a Rensei team for the new directory group |
dsync.group.updated | Renames the team; syncs member list if members array is provided |
dsync.group.deleted | Soft-deletes the Rensei team |
dsync.user.deleted | Calls deprovisionUser() - revokes org memberships, scrubs active sessions |
Only the events listed above trigger platform actions. Unknown event types return 200 { ok: true, detail: "Event type not handled" } so your IdP's delivery retry logic does not stall.
Setup
Enable Directory Sync in WorkOS
In the WorkOS Dashboard, navigate to Organizations → <your-org> → Directory Sync and create a new directory. Select your IdP (Okta, Azure AD, Google Workspace, etc.) and follow the WorkOS setup guide for that provider.
Configure the webhook
WorkOS needs to know where to send directory events. In the WorkOS Dashboard under Webhooks, add a new endpoint:
https://app.rensei.ai/api/scim/webhookThe signing secret configuration is handled by your Rensei deployment operator. Deployment-level setup is covered in the operator docs.
Map groups to roles
Once directory sync is live, open Settings → Members → Directory Groups. For each synchronized group, assign a platform role:
| Role | Capabilities |
|---|---|
admin | Full org admin - settings, billing, key management |
member | Standard access to projects they are a member of |
auditor | Read-only across all projects; can query audit trail |
Role resolution is highest-privilege-wins: if a user belongs to both an admin-mapped group and a member-mapped group, they get admin. The resolution order is: admin → auditor → member.
Group-to-role mapping
The platform stores group mappings in Redis under the key workspace:{id}:scim:group-map. Each entry maps an IdP group ID to a GroupRoleMapping:
interface GroupRoleMapping {
groupId: string // IdP group ID from SCIM
groupName: string // Human-readable name from IdP
role: 'admin' | 'member' | 'auditor'
provider?: string // e.g. "workos", "okta", "azure-ad"
}Mapping changes emit scim.group_mapped or scim.group_unmapped audit events.
User deprovisioning
When dsync.user.deleted fires, the platform looks up the user by their externalId (the IdP user ID stored at sign-in) and calls deprovisionUser(). Deprovisioning:
- Soft-deletes all org memberships for the user
- Invalidates any active sessions
- Emits an audit event for the compliance trail
The user's history (audit events, session records) is preserved for audit purposes - only active access is revoked.
SCIM user state in Redis
The platform tracks each SCIM-managed user in Redis under workspace:{id}:scim:user:{userId}:
interface ScimUser {
id: string
email: string
firstName: string
lastName: string
active: boolean // false after deprovision
scimManaged: boolean // true for SCIM-provisioned users
groups: string[] // current group memberships
}This state is the authoritative source of truth for whether a user is actively managed by the directory - used by the role resolver to enforce real-time group changes.
Troubleshooting
Related pages
- SSO (WorkOS) - authenticate users before they are provisioned
- Members & RBAC - manually manage members and teams
- Audit Trail - SCIM events are hash-chained for compliance