> ## Documentation Index
> Fetch the complete documentation index at: https://modem.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Directory Sync (SCIM)

> Provision and deprovision Modem accounts automatically from Okta or Microsoft Entra ID with SCIM 2.0

Directory Sync keeps Modem's user list in step with your identity provider. When someone is assigned to the Modem application in your directory, an account appears in Modem; when they leave the company or are unassigned, their access is revoked. Modem implements **SCIM 2.0**, and has step-by-step guides for [Okta](/docs/enterprise/scim-okta) and [Microsoft Entra ID](/docs/enterprise/scim-entra).

<Info>
  Directory Sync requires the **Enterprise plan** and is turned on per organization by Modem, together with [Enterprise
  SSO](/docs/enterprise/sso). Contact [support@modem.dev](mailto:support@modem.dev) to have it enabled.
</Info>

## Requirements

* The **Enterprise plan**, with Enterprise SSO enabled for your organization by Modem
* The **owner** role in the Modem organization. Admins and members can open the Directory Sync page but cannot see or change any of it
* [Enterprise SSO](/docs/enterprise/sso) configured first. Directory Sync creates accounts but issues no way to sign in — see [SCIM and SSO are two halves](#scim-and-sso-are-two-halves) below
* Administrator access to your directory, with permission to configure provisioning on the Modem application

## What SCIM does, and does not do

| Directory Sync does                                                | Directory Sync does not                                                                   |
| ------------------------------------------------------------------ | ----------------------------------------------------------------------------------------- |
| Create a Modem account when someone is assigned the application    | Give anyone a way to sign in — that is [SSO](/docs/enterprise/sso)                             |
| Update names and email addresses when they change in the directory | Sync passwords. Modem never accepts a password over SCIM                                  |
| Revoke access when someone is unassigned, deactivated, or deleted  | Delete the Modem account, or the topics, automations, and history attached to it          |
| Set a person's Modem role from the directory group they are in     | Grant the **owner** role. Owners are always promoted by hand in Modem                     |
| Restore access, and the role, when someone is reassigned           | Manage members who were invited directly in Modem, or who joined through domain auto-join |

### SCIM and SSO are two halves

Provisioning an account is not the same as being able to use it. A SCIM-provisioned person has no password and no linked GitHub or Google account, so **single sign-on is how they get in**. Set up [Enterprise SSO](/docs/enterprise/sso) first; the Directory Sync page will tell you to do that before it offers a token.

The two halves meet at one value: the **`externalId`** your directory sends over SCIM must be **the same value** the SAML application sends as the NameID. That is what lets Modem recognise the person signing in as the person the directory provisioned, instead of creating a second account for them. Each setup guide names the exact attribute to use.

<Warning>
  Never match on email. People change email addresses, and matching on email is how one person's account is handed to someone else. Modem
  matches on the immutable directory id and nothing else.
</Warning>

## Connecting a directory

<Steps>
  <Step title="Open Directory Sync in Modem">
    Go to **Settings** → **Directory Sync** in the [Modem dashboard](https://app.modem.dev). If single sign-on is not
    configured yet, finish that first.
  </Step>

  <Step title="Copy the SCIM base URL">
    Modem's endpoint is the same for every organization:

    ```
    https://app.modem.dev/api/auth/scim/v2
    ```

    Your directory may call this the *SCIM connector base URL* (Okta) or the *Tenant URL* (Entra).
  </Step>

  <Step title="Generate a token">
    Click **Generate token**. The token is shown **once** and is never retrievable afterwards — copy it before you
    close the dialog. If you lose it, rotate to a new one; there is no way to read the old one back.
  </Step>

  <Step title="Paste both into your directory and test the connection">
    Both Okta and Entra validate the endpoint and the token before they will save the configuration. Follow the
    [Okta](/docs/enterprise/scim-okta) or [Microsoft Entra ID](/docs/enterprise/scim-entra) guide from here.
  </Step>

  <Step title="Map your directory groups to Modem roles">
    Back on the Directory Sync page, map the groups your directory pushes to **Admin** or **Member**. See
    [Groups and roles](#groups-and-roles).
  </Step>
</Steps>

## The token

The token is a bearer credential. Treat it exactly as you would any other API secret: it can create and deactivate accounts in your Modem organization.

* It is shown **once**, at the moment it is generated. Modem stores only a keyed hash of it and cannot show it again.
* It expires **one year** after it is generated. Rotate before then, or provisioning stops.
* A connection may hold **up to three live tokens at once**. That is the rotation window, not a fleet.
* Every request is over HTTPS. Modem refuses an expired, revoked, or unknown token with `401`.

### Rotating without an outage

**Rotate token** issues a second token alongside the first. Both work, so nothing breaks while you switch:

<Steps>
  <Step title="Rotate">Click **Rotate token** on the Directory Sync page and copy the new value.</Step>
  <Step title="Update the directory">Paste the new token into Okta or Entra and run its test-connection step.</Step>
  <Step title="Revoke the old one">Back in Modem, revoke the previous token. It stops working immediately.</Step>
</Steps>

If you never get to the last step, the old token still expires on its own. Revoke it anyway — a token that is no longer in a directory is a secret with nowhere left to be used from.

### Retiring a connection

**Decommission** retires the connection permanently. It is **irreversible**, and it is not a pause button:

* Every token on the connection stops working immediately.
* Every person the directory provisioned is reconciled to inactive — their access is revoked and their Modem organization membership is removed, exactly as if the directory had deactivated them one by one.
* The directory records themselves are kept, so the history of who was provisioned when is not lost.

Use it when you are disconnecting a directory for good, or migrating to a different one. To migrate, connect the new directory and let it provision everyone **before** decommissioning the old one.

## Lifecycle

| In your directory                 | In Modem                                                                                                        |
| --------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| Assign the application to someone | An account is created, or an existing account is linked, and they join your organization                        |
| Change their name or email        | The Modem profile is updated                                                                                    |
| Put them in a mapped group        | Their Modem role changes to the role that group grants                                                          |
| Unassign or deactivate them       | Access is revoked, their sessions end, and their organization membership is removed. The account itself is kept |
| Reassign or reactivate them       | Access is restored, along with whatever role their groups still grant                                           |
| Delete them from the directory    | The same as unassigning: access is revoked, and the Modem account and everything attached to it is kept         |

<Note>
  Revoking access takes effect **within five minutes**, not instantly. Modem caches a signed session for up to five minutes to avoid a
  database read on every request, so someone who is mid-session may keep it for that long after the directory deactivates them. Every new
  sign-in is refused immediately.
</Note>

<Warning>
  Changing someone's email address in the directory clears their **email verification** in Modem, because a provisioning push is not proof
  that they own the new mailbox. It is restored the next time they sign in through single sign-on. Nothing else about their account
  changes.
</Warning>

## Groups and roles

A directory group grants nothing until you map it. On the Directory Sync page, each group your directory has pushed can be mapped to:

| Modem role | What it grants                                                                                            |
| ---------- | --------------------------------------------------------------------------------------------------------- |
| **Admin**  | Manage members, integrations, and organization settings. See [Team Management](/docs/features/team-management) |
| **Member** | Full use of the product, without organization administration                                              |

Rules worth knowing before you design your groups:

* **Someone in no mapped group is still a member.** Provisioning is itself the access decision — the directory put them in Modem, so they belong here. Mapped groups only raise them above the default.
* **The strongest role wins.** Someone in both an Admin-mapped and a Member-mapped group is an admin.
* **Mappings are keyed on the group's directory id, not its name.** Renaming a group in Okta or Entra does not change who is an admin.
* **The owner role is never granted by a group.** Promote owners by hand in **Settings** → **Team**.
* **Roles granted by hand are never overwritten.** If an admin invited someone in Modem directly, or they joined through domain auto-join, Directory Sync leaves their role alone in both directions — it will neither promote nor demote them.
* After you change a mapping, Modem re-applies it to everyone the directory has already provisioned. You do not need to re-push from the directory.

## Enforcing SSO for provisioned users

Directory Sync adds a switch, **Enforce SSO for provisioned users**, which is **turned on automatically when you connect your first directory**.

With it on, a single sign-on attempt is only accepted if the person is currently listed as active in your directory. Someone the directory has deactivated, deleted, or never provisioned is refused at sign-in with *"Your account is not active"*, even if their identity provider is perfectly happy to vouch for them. This is what closes the gap between "removed from the directory" and "cannot get into Modem".

Turn it **off** while you are migrating — during an initial rollout, while you are switching directories, or any time your directory does not yet list everyone who needs access. With it off, single sign-on works for anyone your identity provider authenticates, exactly as it does without Directory Sync.

<Warning>
  Enforcement is on from the moment the first token is generated. If you connect a directory before it has provisioned your team, turn the
  switch off first, or the people who are not yet in the directory will be locked out.
</Warning>

## Limits and unsupported features

* **A group may contain up to 1,000 direct members.** Larger groups are rejected rather than truncated.
* **Groups may contain users only.** Nested groups and non-user members are rejected — flatten them in your directory.
* **Filters support equality and `and` only.** `or`, `not`, comparison operators, and presence filters are not supported. This matches what Okta and Entra send.
* **Pages hold at most 100 resources.** A directory asking for more is given 100 and the true total, and pages through the rest.
* **Passwords, photos, instant-messaging addresses, and X.509 certificates are ignored.** Modem never accepts a password over SCIM.
* **`User.groups`, bulk requests, `/Me`, ETags, cursors, and sorting are not supported.**
* Custom schema extensions are not supported. The standard Enterprise User extension (`department`, `employeeNumber`, `manager`, and the rest) is accepted.

## Troubleshooting

<AccordionGroup>
  <Accordion title="Test connection fails with 401 Unauthorized">
    The token is wrong, expired, or revoked. Generate a fresh one on the Directory Sync page and paste it again — and check that it was
    pasted whole, without a `Bearer ` prefix and without trailing whitespace.
  </Accordion>

  <Accordion title="Test connection fails with 404, or the directory cannot reach the endpoint">
    Check the base URL. It is `https://app.modem.dev/api/auth/scim/v2` with no trailing slash, and no organization identifier — the
    token is what identifies your organization.
  </Accordion>

  <Accordion title="A user is provisioned but cannot sign in">
    Provisioning creates the account; [single sign-on](/docs/enterprise/sso) is how they use it. Check that the SSO provider is registered,
    that the domain is verified, and that the person is assigned to the SAML application as well as to provisioning.
  </Accordion>

  <Accordion title="Signing in creates a second account instead of using the provisioned one">
    The `externalId` your directory sends does not match the NameID the SAML application asserts. Both have to be the same immutable
    directory id — see the [Okta](/docs/enterprise/scim-okta) or [Microsoft Entra ID](/docs/enterprise/scim-entra) guide for the exact attribute.
  </Accordion>

  <Accordion title="Someone was removed from the directory but is still using Modem">
    Wait five minutes. Modem caches a signed session for up to that long; new sign-ins are refused immediately. If it persists beyond
    that, check that the directory actually deactivated or unassigned them rather than only removing them from a group.
  </Accordion>

  <Accordion title="A group push fails with an error about invalid members">
    Every member has to be a user Modem already knows about, in the same connection. Push the users before the groups, and flatten any
    nested groups — Modem takes direct user members only.
  </Accordion>

  <Accordion title="A group mapping is not changing anyone's role">
    Check that the group appears in the group list on the Directory Sync page. It only appears once the directory has actually pushed
    it, which for Okta means the group is in **Push Groups** and for Entra means it is in scope for provisioning.
  </Accordion>
</AccordionGroup>

## Set up your directory

<CardGroup cols={2}>
  <Card title="Okta" icon="https://mintcdn.com/modem-844d7a4a/Wr2r4IRr97lNQiQb/icons/shield.svg?fit=max&auto=format&n=Wr2r4IRr97lNQiQb&q=85&s=ee1ca3093fcbdf45ec5dc1a74652bed6" href="/docs/enterprise/scim-okta" width="24" height="24" data-path="icons/shield.svg">
    SCIM 2.0 provisioning on the Modem app integration, with group push.
  </Card>

  <Card title="Microsoft Entra ID" icon="https://mintcdn.com/modem-844d7a4a/Wr2r4IRr97lNQiQb/icons/shield.svg?fit=max&auto=format&n=Wr2r4IRr97lNQiQb&q=85&s=ee1ca3093fcbdf45ec5dc1a74652bed6" href="/docs/enterprise/scim-entra" width="24" height="24" data-path="icons/shield.svg">
    Automatic provisioning on the Modem enterprise application.
  </Card>

  <Card title="Enterprise SSO" icon="https://mintcdn.com/modem-844d7a4a/Wr2r4IRr97lNQiQb/icons/shield.svg?fit=max&auto=format&n=Wr2r4IRr97lNQiQb&q=85&s=ee1ca3093fcbdf45ec5dc1a74652bed6" href="/docs/enterprise/sso" width="24" height="24" data-path="icons/shield.svg">
    Set this up first — it is how provisioned users sign in.
  </Card>

  <Card title="Team Management" icon="https://mintcdn.com/modem-844d7a4a/Wr2r4IRr97lNQiQb/icons/users.svg?fit=max&auto=format&n=Wr2r4IRr97lNQiQb&q=85&s=32a2de5620a3659206db1c3d1aff5a06" href="/docs/features/team-management" width="24" height="24" data-path="icons/users.svg">
    What each Modem role can do.
  </Card>
</CardGroup>
