> This page is for version v4 (default).
> For other versions, use one of these documentation indexes:
> - v4 (default): https://help.getzep.com/v4/llms.txt
> - v3: https://help.getzep.com/v3/llms.txt
> - v2: https://help.getzep.com/v2/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://help.getzep.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://help.getzep.com/_mcp/server.

# SCIM provisioning

> **Info**
>
> SCIM provisioning is in beta. It requires the Enterprise plan. Zep turns on SCIM for each Enterprise account on request. To ask for access, contact [Zep sales](https://www.getzep.com/pricing).

System for Cross-domain Identity Management (SCIM) lets an identity provider (IdP) create, update, suspend, and remove Members and Groups in a Zep account. OpenID Connect (OIDC) authenticates each person through an Enterprise SSO realm. SCIM provisions account data; it does not authenticate sign-ins.

An IdP can provision a Member before the person's first sign-in. The person signs in through the realm. An administrator maps SCIM Groups to Zep roles.

## Key terms

* **SCIM User:** The SCIM record that represents one account Membership.
* **Member:** A person's identity in Zep. A Member can have Memberships in several accounts.
* **Membership:** The link between a Member and one account. A Membership has an `active`, `pending`, or `suspended` status.

## Requirements

SCIM is available on managed cloud. Zep does not currently support SCIM on Bring Your Own Cloud (BYOC) deployments. On a BYOC deployment, `/scim/v2` returns `404`.

The account must meet these conditions:

* The account has an Enterprise plan and role-based access control (RBAC).
* Zep has turned on SCIM for the account.
* The account has an enabled Enterprise SSO realm with at least one approved email domain.
* An Account Owner has signed in through the realm at least once before token creation.

The [Enterprise SSO guide](/enterprise-sso) explains realm setup.

## Set up SCIM

#### Confirm Enterprise SSO

Confirm that the realm is enabled. Confirm that it has an approved email domain.

#### Create a token

Open the **Provisioning (SCIM)** tab (**Account > Single sign-on > Provisioning (SCIM)**). Select **Create token**. Enter a label. Select **Create token** again. Copy and save the token secret. Zep shows it once.

#### Keep JIT on while you test

In the Provisioning (SCIM) tab, turn on **SCIM provisioning** and **Allow JIT provisioning**. The account uses `scim_and_jit` mode. [Provisioning modes](#provisioning-modes) explains each mode.

#### Enter the SCIM connection details

Copy the full SCIM base URL from the Provisioning (SCIM) tab. Enter the URL and token in the IdP.

#### Map the user name

Map the IdP email to `userName`. The email must match the OIDC email and use an approved realm domain.

#### Test one user

Assign one test user in the IdP. Confirm that Zep creates a SCIM User: in **Account > Members**, open the Member. The Member has an `Account Viewer` role binding that shows **Managed by SCIM**. Then sign in as the test user through the realm. This sign-in links the SCIM User to the OIDC identity.

> **Note**
>
> In `scim_and_jit` mode, the test sign-in succeeds through JIT even when SCIM did not create the SCIM User. A successful sign-in does not prove that SCIM works. Look for the **Managed by SCIM** binding.

#### Adopt existing Members

Assign the remaining users and Groups in the IdP, then sync. Zep matches each SCIM User to an existing Member by `userName` (the email) and links them. The Member keeps the manual role bindings. Zep adds an `Account Viewer` role binding managed by SCIM to each Member.

#### Push Groups and map roles

Push the IdP Groups. In **IdP groups**, map each Group to a Zep role. Select a project for a project role.

#### Wait for Group mappings

> **Warning**
>
> If you remove manual role bindings before the Group mappings show **Applied**, access can stop for a short time.

Wait until every Group in **IdP groups** shows **Applied**. Then remove the manual role bindings that the mappings now give.

#### Select the final mode

After at least one active linked SCIM User has signed in through SSO, turn off **Allow JIT provisioning** if JIT must not create Members. See [When can you turn off JIT?](#when-can-you-turn-off-jit)

## Microsoft Entra ID

You can add provisioning to the Enterprise application that you use for SSO, or create a separate non-gallery application.

| Setting             | Value                                                                                |
| ------------------- | ------------------------------------------------------------------------------------ |
| Provisioning mode   | Automatic                                                                            |
| Tenant URL          | The SCIM base URL shown in the Provisioning (SCIM) tab                               |
| Secret token        | The SCIM token                                                                       |
| `userName` source   | Use `userPrincipalName` when it matches the OIDC email. Use `mail` when it does not. |
| `externalId` source | Entra ID uses `mailNickname` by default. Use `objectId` for a stable identifier.     |
| Scope               | **Sync only assigned users and groups**                                              |

Entra ID sends `active = false` when an administrator unassigns a user. In Zep, this suspends the Membership. Suspension does not delete the SCIM User.

## Okta

The Okta integration uses the realm's OIDC app integration with SCIM provisioning enabled.

| Setting                    | Value                                                  |
| -------------------------- | ------------------------------------------------------ |
| SCIM connector base URL    | The SCIM base URL shown in the Provisioning (SCIM) tab |
| Unique identifier field    | `userName`                                             |
| Authentication mode        | HTTP Header with a bearer token                        |
| Authorization header value | `Bearer ` followed by the SCIM token                   |
| Provisioning actions       | Push New Users, Push Profile Updates, and Push Groups  |

An account is fully managed by SCIM when every Member has a SCIM User. Do not turn on **Import Users** until the account is fully managed by SCIM.

Okta sends deactivation as `active = false` and does not send DELETE by default. The Membership stays suspended until the IdP sends DELETE or an administrator removes the Member after SCIM provisioning is off or after a disconnect.

## Attribute mapping

Configure only the SCIM attributes in these tables.

| User attribute                                                                                                                           | Use in Zep                                                                                                                                                                        |
| ---------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `userName`                                                                                                                               | Required. This value is the Member email. It must use an approved realm domain.                                                                                                   |
| `externalId`                                                                                                                             | Optional, case-sensitive identifier. It must be unique in the account when present.                                                                                               |
| `active`                                                                                                                                 | `true` sets the Membership to active or pending. `false` suspends the Membership. It does not delete the SCIM User.                                                               |
| `name.givenName`, `name.familyName`                                                                                                      | Optional Member profile fields.                                                                                                                                                   |
| `displayName`                                                                                                                            | Optional Member profile display name.                                                                                                                                             |
| `department`, `employeeNumber`, `manager.value` in the enterprise extension `urn:ietf:params:scim:schemas:extension:enterprise:2.0:User` | Optional informational fields. On `POST` and `PUT`, Zep reads these attributes only from the enterprise extension. A `PATCH` can also use the paths without the extension prefix. |
| `emails`                                                                                                                                 | Not used. Zep uses `userName` as the email. A filter on `emails.value` compares the value with `userName`.                                                                        |
| `groups`                                                                                                                                 | Read-only. Zep returns the Groups that contain the SCIM User.                                                                                                                     |

For Groups, `displayName` is required. `externalId` is optional. `members[].value` contains SCIM User IDs from the same account. The IdP does not assign Zep roles through User attributes. Map Groups to roles in Zep.

## Users, Groups, and roles

### User lifecycle

When SCIM creates a User, Zep creates a Membership or adopts an existing one. A new Membership is `pending` until the person signs in through the realm, unless the IdP sends `active = false`. SCIM does not send an invite email.

When SCIM adopts an existing Member, the Member keeps the manual role bindings. Zep adds an `Account Viewer` binding managed by SCIM.

When the IdP sets `active` to `false`, Zep suspends the Membership before it returns the response. The role bindings stay. When the IdP sets `active` to `true`, the Membership becomes `active` if the person has signed in through the realm. Otherwise, it becomes `pending`.

A suspended SCIM User stays visible to the IdP with `active = false`. Suspension stops dashboard access no later than 60 seconds after the SCIM response. The Member cannot sign in through the realm. Suspension does not delete project API keys, projects, graphs, or data. API keys are project principals, not Member principals.

When the IdP sends DELETE for a SCIM User, Zep removes the Membership, its role bindings, and the User from SCIM Groups. Zep deletes the Member only when the person has no Membership in another account.

### Account Owner protections

* SCIM cannot delete an Account Owner, regardless of the Membership status.
* SCIM cannot suspend the last active Account Owner. A pending or suspended Owner does not count as active.
* Both requests return `400` with `scimType: mutability`.
* To remove a SCIM-managed Owner, make sure another active Member is an Owner. Remove the Account Owner role in the dashboard. Then delete the SCIM User in the IdP.

### Group role mappings

An IdP can create Groups and update their Members. A Group has no role effect until an administrator creates a mapping in **IdP groups**. A mapping connects one Group to one Zep role. A project role also names a project.

An Account Owner or Account Admin can manage mappings:

| Zep role          | Account Admin can map | Account Owner can map |
| ----------------- | --------------------- | --------------------- |
| `Account Admin`   | No                    | Yes                   |
| `Billing Admin`   | No                    | Yes                   |
| `Account Viewer`  | Yes                   | Yes                   |
| `Project Creator` | Yes                   | Yes                   |
| `Project Admin`   | Yes                   | Yes                   |
| `Project Editor`  | Yes                   | Yes                   |
| `Project Viewer`  | Yes                   | Yes                   |
| `Account Owner`   | Never                 | Never                 |

Only a manual change in the dashboard can give the Account Owner role.

Mappings for `Project Admin`, `Project Editor`, and `Project Viewer` include a project. Other roles do not name a project.

When an administrator creates a mapping, its status is **Applying**. Zep changes it to **Applied** when every Group member has the mapped role. If the update does not finish in 15 minutes, the status changes to **Delayed**. Zep has no Group size limit and tests Groups with up to 50,000 members.

SCIM-managed role bindings have the source `scim`. The Members drawer labels these bindings **Managed by SCIM**. Manual bindings have the source `manual`. SCIM does not change manual bindings during Group updates. An administrator can add or remove manual bindings for a SCIM-managed Member.

## Provisioning modes

The **SCIM provisioning** and **Allow JIT provisioning** switches set the account mode:

| Mode           | SCIM provisioning | Allow JIT provisioning | SCIM API      | First sign-in without a Membership                                    |
| -------------- | ----------------- | ---------------------- | ------------- | --------------------------------------------------------------------- |
| `jit`          | Off               | Not shown              | Returns `403` | JIT creates an `Account Viewer` Membership when the realm allows JIT. |
| `scim_and_jit` | On                | On                     | Available     | JIT creates an `Account Viewer` Membership when the realm allows JIT. |
| `scim`         | On                | Off                    | Available     | Zep denies sign-in until SCIM provisions the person.                  |

In `scim` mode, an existing Member without a SCIM User can still sign in. The `scim.provisioning_mode.updated` audit event shows the mode name.

### When can you turn off JIT?

> **Note**
>
> Zep lets you turn off **Allow JIT provisioning** only after at least one active linked SCIM User has signed in through SSO. Before that, the dashboard shows the error **SCIM mode requires an active linked SCIM User**, and the mode does not change.

## Token rotation and revocation

Only an Account Owner can create, list, or revoke SCIM tokens. A SCIM token works for one account. An account can have up to two active tokens. Zep shows each token secret once, when you create it.

To rotate a token, create a second token, update the IdP to use it, then revoke the old token:

#### Create a second token

Create a token in the Provisioning (SCIM) tab.

#### Update the IdP

Change the IdP to use the new token.

#### Revoke the old token

Revoke the old token in the Provisioning (SCIM) tab.

To revoke a token without rotation:

> **Warning**
>
> When you revoke a token that the IdP still uses, provisioning stops at once. The IdP gets 401 for each SCIM request until you enter a new token.

#### Revoke the token

Revoke the token in the Provisioning (SCIM) tab.

## Disconnect SCIM

Only an Account Owner can disconnect SCIM. The confirmation shows counts for SCIM Users, Groups, Group mappings, and SCIM-managed role bindings.

When an Owner confirms the disconnect, Zep immediately revokes every SCIM token and changes the mode to `jit`. The IdP receives `401` for later SCIM requests.

Zep completes the remaining work in the background. Zep deletes SCIM Users, Groups, and mappings. Zep converts role bindings granted by current SCIM Users, Group membership, and mappings to manual bindings. Zep removes other SCIM bindings. Zep keeps existing manual bindings.

The disconnect does not create, suspend, reactivate, or remove Members. Membership status stays the same. Zep preserves each Member's effective roles and manual bindings. The dashboard shows **Disconnecting** until the work completes. The dashboard shows **Delayed** if the work does not complete within 15 minutes. After completion, the dashboard shows **Disconnected**.

If the mode was `scim` and the realm allows JIT, a first sign-in after disconnect can create an `Account Viewer` Membership.

## Supported SCIM API

All endpoints below use the `/scim/v2` base path.

| Endpoint                 | Methods                         |
| ------------------------ | ------------------------------- |
| `/ServiceProviderConfig` | `GET`                           |
| `/Schemas`               | `GET`                           |
| `/ResourceTypes`         | `GET`                           |
| `/Users`                 | `GET`, `POST`                   |
| `/Users/{id}`            | `GET`, `PUT`, `PATCH`, `DELETE` |
| `/Groups`                | `GET`, `POST`                   |
| `/Groups/{id}`           | `GET`, `PUT`, `PATCH`, `DELETE` |

Filters support only the `eq` operator with a quoted value. A filter can have up to two conditions joined by `and`. Both conditions must match:

| Resource | Filter attributes                                                      | Two conditions                                                                                                                   |
| -------- | ---------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| Users    | `userName`, `emails.value`, `externalId`, `displayName`, `id` (a UUID) | Use two different attributes. Because `userName` and `emails.value` compare the same email, you can use them in both conditions. |
| Groups   | `id` (a UUID), `displayName`, `externalId`                             | Use two different attributes. The same attribute in both conditions returns `400` with `scimType: invalidFilter`.                |

A filter on `emails.value` compares the value with `userName`. For example, `userName eq "ana@acme.com" and emails.value eq "ana@acme.com"` returns the User with that email. `userName eq "a@acme.com" and userName eq "b@acme.com"` returns an empty list, because no User matches both conditions. Other operators or unsupported attributes return `400` with `scimType: invalidFilter`.

The list endpoints use `startIndex` and `count` for paging. `startIndex` starts at 1. The default `count` and the maximum `count` are 100.

All User responses support the `attributes` and `excludedAttributes` query parameters. For Groups, only `GET` responses support these parameters. A Group `POST`, `PUT`, or `PATCH` response always contains the full Group. Zep always returns `id`, `schemas`, and `meta`. For Groups, Zep also always returns `displayName`. Zep returns `userName` by default. If you set `attributes`, include `userName` to keep it in the response. To get Groups without `members`, use `excludedAttributes=members`.

User and Group `PATCH` requests support the `add`, `replace`, and `remove` operations.

Requests with a body accept `application/scim+json` or `application/json` as the `Content-Type`, with case-insensitive matching.

The Service Provider Configuration reports these features as unsupported:

* Bulk operations
* ETag
* Sort
* `changePassword`

## Limits and errors

The default rate limit is 50 requests per second for each account. Both active tokens share the limit. To raise the limit, contact [support@getzep.com](mailto:support@getzep.com).

The request body limit is 1 MiB. A larger body returns `413`.

### SCIM API errors

| Status | Cause                                                                                                                                                                                                                                                                 |
| ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | The request has an invalid value, filter, or syntax. Suspending the last active Account Owner or deleting an Account Owner returns `400` with `scimType: mutability`.                                                                                                 |
| `401`  | The token is missing, invalid, or revoked. Disconnect revokes all SCIM tokens.                                                                                                                                                                                        |
| `403`  | The account lacks the Enterprise plan, RBAC, SCIM enablement, an enabled realm, or an approved domain, or the mode is `jit`.                                                                                                                                          |
| `404`  | The resource is not in the token's account. A repeated DELETE also returns `404`.                                                                                                                                                                                     |
| `409`  | The request conflicts with an existing User or Group, or a disconnect is in progress. A Group `externalId` must be unique within the account when it is not null. For Groups without an `externalId`, `displayName` must be unique among those Groups in the account. |
| `413`  | The request body is larger than 1 MiB.                                                                                                                                                                                                                                |
| `429`  | The account exceeds its request rate limit. The response includes `Retry-After`.                                                                                                                                                                                      |

### Dashboard errors

| Status | Cause                                                                                  |
| ------ | -------------------------------------------------------------------------------------- |
| `403`  | A non-Owner tries to disconnect SCIM.                                                  |
| `409`  | A token, mode, or Group mapping change is requested while a disconnect is in progress. |

## Troubleshooting

| Symptom                                                             | Cause                                                                              | Fix                                                                                                          |
| ------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| The SCIM User does not link to the OIDC identity.                   | `userName` does not match the email in the OIDC ID token.                          | Map `userName` to the same email that the realm sends.                                                       |
| Creating or updating a SCIM User returns `400` with `invalidValue`. | The email domain is not approved for the realm.                                    | Approve the domain in the realm, then retry the request.                                                     |
| Token creation fails.                                               | An Account Owner has not signed in through the realm.                              | Sign in as an Account Owner through the realm, then create the token.                                        |
| SCIM requests return `403`.                                         | The mode is `jit`, or the account does not meet the [requirements](#requirements). | Turn on SCIM provisioning in the Provisioning (SCIM) tab. Make sure that the account meets the requirements. |
| You cannot turn off **Allow JIT provisioning**.                     | No active linked SCIM User has signed in through SSO.                              | See [When can you turn off JIT?](#when-can-you-turn-off-jit)                                                 |