§06 · Identity & access

Directory sync

Pull users and groups into Exo from your directory on a schedule. Exo connects out to LDAP, Microsoft Entra, or Google Workspace, reconciles people and groups, and keeps memberships current between logins.

Directory sync is the pull half of provisioning: Exo reaches out to your directory and mirrors users and groups in. Configure it under Dashboard → Identity providers (needs idp:write). Three sources: LDAP / Active Directory, Microsoft Entra via Graph, and Google Workspace. Pair it with SSO for the sign-in itself.

Push vs pull

If your IdP can push (Okta, Entra with SCIM enabled), prefer SCIM: it's near-real-time and the IdP owns the schedule. Reach for pull-based directory sync when the IdP can't push, when you run on-prem AD, or when you want Exo to own the cadence. Both write to the same users and groups, so pick one source of truth per directory.

LDAP / Active Directory

Exo binds to your LDAP server and runs the user and group searches you define. Provide a read-only service account for the bind.

FieldMaps toNotesExample
HosthostLDAP server hostname (required)dc1.acme.internal
PortportOptional; 389 (starttls) / 636 (ldaps)636
TLS modetls_modestarttls | ldaps | noneldaps
Base DNbase_dnSearch root, e.g. dc=corp,dc=example,dc=comdc=acme,dc=com
Bind DNbind_dnService-account DN used to authenticatecn=exo-sync,ou=svc,dc=acme,dc=com
Bind passwordbind_passwordWrite-only after save
User filteruser_searchLDAP filter selecting user entries(objectClass=user)
Group filtergroup_searchLDAP filter selecting group entries(objectClass=group)
Sync intervalsync_interval_secondsHow often Exo pulls (0 = scheduler default)1800

Microsoft Entra (Graph)

Register an app in Entra, grant it directory read permissions, and give Exo the tenant and client credentials. Exo uses Graph delta queries, so after the first full sync it pulls only changes. On the Entra side, everything happens in the Entra admin center (or the Azure portal, same screens):

  1. Identity → Applications → App registrations → New registration. Name it something like exo-directory-sync; no redirect URI needed. Note the Application (client) ID and Directory (tenant) ID from the overview page.
    An app registration's Overview page with the Application (client) ID highlighted
    The app registration's Overview page carries both IDs Exo needs: Application (client) ID and Directory (tenant) ID.
  2. API permissions → Add a permission → Microsoft Graph → Application permissions. Add User.Read.All and GroupMember.Read.All, then Grant admin consent. Read-only permissions are sufficient for sync; without admin consent the sync will authenticate but read nothing.
    The API permissions page with Add a permission highlighted
    API permissions → Add a permission → Microsoft Graph → Application permissions. Grant admin consent after adding.
  3. Certificates & secrets → New client secret. Copy the secret value immediately; Entra shows it once.
    The Certificates and secrets page with the Add a client secret panel open
    Certificates & secrets → New client secret. Note the expiry: Entra caps secrets at 24 months.

Then, in Exo: Identity → Identity Providers → Microsoft Graph pull, and paste the three values in:

The Add Microsoft Graph pull dialog in the Exo dashboard
Identity → Identity Providers → Microsoft Graph pull. Blank sync interval = 1800s (30 min); a full reconcile runs daily to catch drift.
FieldMaps toNotesExample
Tenant IDtenant_idEntra (Azure AD) directory tenant12345678-9abc-def0-1234-56789abcdef0
Client IDclient_idApp registration application ID23456789-abcd-ef01-2345-6789abcdef01
Client secretclient_secretWrite-only after savewxy8Q~…
ScopesscopesOptional; Graph scopes for directory readhttps://graph.microsoft.com/.default
Sync intervalsync_interval_secondsPull cadence (0 = scheduler default)1800

Google Workspace

Create a service account with domain-wide delegation, authorize the Admin SDK Directory scopes, and name an admin to impersonate. Paste the service-account key JSON into the editor.

FieldMaps toNotesExample
Admin emailadmin_emailAdmin the service account impersonatesadmin@acme.com
Primary domaindomainOptional; your Workspace domainacme.com
Service account keyservice_account_jsonKey JSON, write-only after save{"type": "service_account", …}
Sync intervalsync_interval_secondsPull cadence (0 = scheduler default)1800

Sync cadence & runs

Each provider syncs on its own interval (or the scheduler default when set to 0). Use Sync now on the provider row to force an immediate pull, and Runs to inspect recent history: last success, last error, and the resume cursor. Connection secrets and certificates are encrypted at rest; the dashboard never renders them back.

Groups & roles

Synced groups appear under Dashboard → Groups marked IdP-sourced: the directory owns their membership, so you can't edit it by hand. Groups don't grant roles; a user's role is assigned directly, one per user, and synced users land as Member until an admin changes it. What groups give you is scoping: use them as principals on per-agent access lists and skill grants. See Roles & permissions.