Skip to content

Directory Connectors

Roster separates the external system from the code that talks to it.

TermMeaning
ProviderExternal source of truth such as Entra ID, Active Directory, Okta, Workday, SAP, or CSV.
ConnectorRoster-owned integration code for one provider or provider family.
ResolverQuery path that uses materialized Roster data to answer routing questions.

Authentication providers configured for human login are separate from roster data providers. In sync and resolver docs, provider means external roster data source.

ConnectorProvider pathNotes
entraMicrosoft Graph v1.0Microsoft Entra directory users and groups.
oktaOkta Core API v1Okta directory users, groups, and memberships.
google_workspaceAdmin SDK Directory API v1Google Workspace users, groups, and memberships.
workdayWorkday RaaS JSON custom reportsTenant-defined workers, organizations, memberships.
ldapLDAP v3 over LDAP or LDAPSActive Directory or LDAP-compatible directories.
csvMounted data volume, S3, or SFTPFile-based records for batch integration workflows.

Use ldaps:// for production LDAP connectors. Plain ldap:// should be limited to isolated directory sources that cannot present a valid LDAPS certificate.

Refresh schedules use 5-field UTC cron expressions. When no schedule is set, the worker defaults to hourly refresh with 0 * * * *.

Worker refresh starts from cached records and attached groups. It refreshes their profiles and discovers the readable subgroup hierarchy required by those group associations, reconciling direct edges at each level. It does not import an entire directory or unrelated groups. Existing saved associations benefit from the normal refresh schedule without configuration changes or reattachment.

For self-hosted deployments, encrypted provider secrets require:

Terminal window
ROSTER_PROVIDER_SECRET_ENCRYPTION_KEY=<generated-provider-secret-encryption-key>

The Platform participant picker can search some connectors live so admins do not need to materialize a full directory before selecting a user or group:

  • CSV connectors read configured CSV files directly
  • Microsoft Entra ID queries Microsoft Graph directly
  • Okta queries the Okta Core API directly
  • Google Workspace queries the Admin SDK Directory API directly
  • Workday queries configured RaaS JSON custom report endpoints directly
  • primary LDAP connectors query LDAP directly

Secondary LDAP connectors remain metadata sources for now. They are searched from materialized records when matching primary connector results.

After an admin selects a user or group, Roster caches only the selected record in directory_records and directory_record_sources. Selected groups also cache the direct membership edges needed through their subgroup hierarchy. Scheduled refresh maintains that hierarchy without browsing unrelated groups.

Interactive group association reads direct membership before saving the association. To keep that request responsive and protect the directory and Roster database, a group can contain up to 10,000 direct members and the lookup must complete within 30 seconds. Use a smaller directory group if either limit is reached. Scheduled connector refreshes continue to maintain memberships for groups that have already been associated.

New records enter the cache through explicit actions such as live browse, manual association, or import flows. Scheduled worker refresh does not discover new standalone records on its own, except for direct members needed by an already-cached participant group, including reachable subgroup members.

Attach the parent group only. Resolve includes effective users through up to 10 subgroup levels by default, with the attached root at level 0. Users in a level-10 group are included; a new group at level 11 exceeds the default bound. Set ROSTER_DIRECTORY_GROUP_MAX_DEPTH to configure 1–32 levels at container startup. Shared groups retain each parent relationship and cycles terminate without repeated users. Graph membership and usage are deduplicated by stable directory identity. Resolve’s existing contact presentation, including e-mail coalescing, is preserved.

This matrix describes the nested-membership paths implemented in Roster. Source conditions and live validation are separate: a source permitting nested groups does not establish that every tenant or group type has been validated.

In this compatibility matrix, ✅ means implemented support under the stated conditions, including Workday’s required report contract; ❌ means native nesting is unavailable. These are support indicators, not live-test results.

ConnectorNested-group support in RosterConditions and source limitations
✅ Microsoft Entra IDSupported for compatible security groupsGraph must return readable direct user/group memberships. The group type and tenant must allow nesting; Microsoft 365 groups cannot be nested.
✅ LDAP / Active DirectorySupported for configured DN-based relationshipsmember and DN-only uniqueMember can identify users or groups within the configured search bases/classes. memberUid supplies direct users only.
✅ CSVSupported with typed membership rowsGroup edges require group_external_id,member_type,member_external_id, with member_type=group. The legacy user-to-group format remains supported.
✅ Google WorkspaceImplemented when direct GROUP members are readableDirectory API responses must provide the direct group relationship and stable member IDs. Delegated access/read permissions must cover every reachable group.
✅ Workday — conditionalConditional on configured reportsUser, group and membership reports must provide complete direct typed relationships with stable IDs. Flattened user lists do not establish a group hierarchy.
❌ OktaNative nesting not applicable; flat user membership supportedThe source exposes group users rather than a native group-to-group hierarchy. Roster preserves the flat connector and does not infer missing parent/child edges.

These membership rules apply to the primary directory source. Secondary connectors remain enrichment sources for matched records.

Microsoft documents which group types can be nested. Google documents group members and required authorization. The CSV guide and Workday guide describe their file/report contracts. LDAP’s optional UID suffix form of uniqueMember is unsupported; use the supported DN-based schema.

Okta’s group documentation states that native nested groups are unavailable. When importing nested AD groups, Okta imports the groups and assigns users to them, including the parent. That flattened user membership does not preserve an authoritative group-to-group edge. Shared users alone cannot establish a parent/ child relationship, so Roster cannot faithfully reconstruct the original hierarchy. The Okta connector continues to support users, groups, paging and flat membership through /api/v1/groups/{id}/users; it has not been removed or disabled.

Implemented support and completed live tests are separate. The Entra security- group fixture, OpenLDAP and real local CSV files were exercised on SQLite and PostgreSQL, including nested refresh and membership changes. A real Google Workspace parent with two subgroup levels also passed initial association and worker refresh on both engines, with unique users and complete coverage; its confirmed manual removal/restoration cycle returned 2 → 1 → 2 unique users without reassociation or identity changes. Its depth boundary and multi-page behavior remain unvalidated. Large-group Entra pagination, AD-specific GUID/member ranges and actual Workday reports still require validation. Local CSV results do not certify S3/SFTP storage or every source schema. The support conditions above remain applicable to each deployment.

In isolated fixture tests, model-backed Resolve also returned the exact expected users through public REST and MCP for Entra, Google Workspace, OpenLDAP and local CSV on both databases, using OpenAI Responses with gpt-5.5 at low effort. These are fixed routing scenarios, not a general model-quality certification. Contact identities are returned in result.users; the generated answer can name only the responsible role, and model-generated reservations remain visible.

Nested discovery is also bounded by 1,000 groups, 10,000 distinct users, 50,000 membership entries and 2,000 pages per root. Interactive association keeps its existing 10,000-direct-member and 30-second limits. Additional subgroup work uses the remaining time; background nested discovery has a 120-second per-root budget. These are Roster safeguards, not provider nesting limits or performance guarantees.

When only additional subgroup discovery is incomplete, Roster preserves the complete root association and existing flat behavior, records incomplete coverage and retries on refresh. Resolve uses its existing caveats field to explain incomplete coverage. It must not be interpreted as a complete hierarchy. An incomplete direct group snapshot never deletes or renews that group’s old memberships; their original 24-hour expiry remains in effect. Independently complete groups can still refresh. Write-side product quotas retain their existing whole-group rollback behavior and do not truncate Resolve output.

API and MCP directory-record search remains cache-only. It searches Roster’s materialized records and does not call upstream connectors live.