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

# Setup SCIM

> Enable real-time user and group provisioning from any SCIM 2.0-capable identity provider to Bifrost Enterprise.

Bifrost exposes a SCIM 2.0 endpoint that any compatible identity provider can push user and group changes to in real time - new users are provisioned, deactivated users are suspended, and group memberships are updated without waiting for the next background sync cycle.

<Note>
  Complete [SSO using OIDC](./oidc) before setting up SCIM. SCIM provisioning runs alongside your OIDC integration - it does not replace it.
</Note>

***

## Step 1: Enable SCIM in Bifrost

<Steps>
  <Step title="Open your OIDC provider">
    In your Bifrost dashboard, go to **Governance** → **User Provisioning** and open your configured Generic OIDC provider.

    <Frame caption="The provider dashboard showing your connection details, attribute mappings, and quick actions.">
      <img src="https://mintcdn.com/bifrost-dev/BK4EFQebtGOm33sD/media/user-provisioning/generic-oidc/bifrost-provider-dashboard.png?fit=max&auto=format&n=BK4EFQebtGOm33sD&q=85&s=e1ebdc3e9cd2e8fb907515455f511ce3" alt="Bifrost Generic OIDC provider dashboard showing connection details, attribute mappings, and quick action buttons" width="2912" height="1664" data-path="media/user-provisioning/generic-oidc/bifrost-provider-dashboard.png" />
    </Frame>
  </Step>

  <Step title="Enable SCIM provisioning">
    Click the settings icon to open **Provider Configuration**.

    Toggle on **Enable SCIM Provisioning** and click **Verify & Next**.

    <Frame caption="Enable SCIM Provisioning - the SCIM endpoint URL and bearer token are generated after saving.">
      <img src="https://mintcdn.com/bifrost-dev/BK4EFQebtGOm33sD/media/user-provisioning/generic-oidc/bifrost-enable-scim.png?fit=max&auto=format&n=BK4EFQebtGOm33sD&q=85&s=c1c7de23c5d545e8c5ef11dc6053992c" alt="Bifrost Provider Configuration with Enable SCIM Provisioning toggle turned on" width="2912" height="1664" data-path="media/user-provisioning/generic-oidc/bifrost-enable-scim.png" />
    </Frame>
  </Step>

  <Step title="Copy the SCIM credentials">
    After saving, Bifrost shows a **Setup Complete** dialog with:

    * **SCIM Endpoint URL** - the base URL your IdP will send provisioning requests to (e.g. `https://<your-bifrost-domain>/scim/v2`)
    * **Provisioning Token** - the bearer token your IdP uses to authenticate requests

    <Frame caption="Setup Complete - copy the SCIM Endpoint URL and Provisioning Token before closing this dialog.">
      <img src="https://mintcdn.com/bifrost-dev/BK4EFQebtGOm33sD/media/user-provisioning/generic-oidc/bifrost-scim-token-dialog.png?fit=max&auto=format&n=BK4EFQebtGOm33sD&q=85&s=cfd39e68e20cb8864b4b88f949eb8034" alt="Bifrost Setup Complete dialog displaying the SCIM Endpoint URL and one-time Provisioning Token" width="2912" height="1664" data-path="media/user-provisioning/generic-oidc/bifrost-scim-token-dialog.png" />
    </Frame>

    <Warning>
      The provisioning token is only shown once. Store it somewhere safe before closing. You can rotate it later, but the previous token becomes invalid immediately.
    </Warning>
  </Step>
</Steps>

***

### Alternative: seed the token declaratively (Helm / config.json)

If you manage Bifrost with Helm or a static `config.json` (GitOps), you can seed the **Provisioning Token** yourself instead of generating it in the dashboard.

<Steps>
  <Step title="Generate a token">
    ```bash theme={null}
    openssl rand -base64 32 | tr '+/' '-_' | tr -d '='
    ```

    This produces a URL-safe token in the same format Bifrost mints internally.
  </Step>

  <Step title="Add it to your SCIM config">
    Helm `values.yaml`:

    ```yaml theme={null}
    bifrost:
      scim:
        enabled: true
        provider: "generic"
        config:
          issuerUrl: "https://idp.company.com"
          clientId: "..."
          clientSecret: "env.OIDC_CLIENT_SECRET"
          provisioningToken: "env.SCIM_PROVISIONING_TOKEN"   # or the literal token
          claimScimAttributes:                                # per-claim SCIM interpretation
            groups:
              attributeType: "group"        # "user" (SCIM User attribute) or "group" (match SCIM Group)
              attributeValue: "displayName"
          claimsSyncMode: "both"                                # provisioning source: "both" (SCIM + login claims) or "scim" (SCIM only - ignore login claims)
    ```

    The same keys (`provisioningToken`, `claimScimAttributes`, `claimsSyncMode`) apply directly under `scim_config.config` in a raw `config.json`.
  </Step>
</Steps>

<Warning>
  Keep the token in a Kubernetes Secret and reference it with the `env.` prefix - never commit the literal value. Rotating the token in the dashboard invalidates any value seeded here.
</Warning>

Then use this token as the **Bearer Token** and your deployment's SCIM endpoint as the **SCIM Base URL** in [Step 2](#step-2-configure-your-idp-to-push-scim-to-bifrost) below.

***

### Provisioning source

The provider configuration includes a **Provisioning source** setting that controls whether IdP login claims still provision users, or whether SCIM is the sole source of truth:

| Option                              | Config value | Behavior                                                                                                                                                                                                              |
| ----------------------------------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **SCIM and login claims** (default) | `both`       | Both SCIM and IdP login / token-refresh claims create and update users, roles, teams, and business units.                                                                                                             |
| **SCIM only - ignore login claims** | `scim`       | SCIM is the sole source of truth. OIDC claims will be ignored and will never create or update users from claims - new users must be pushed by SCIM. Users not already provisioned by SCIM are denied access at login. |

Choose **SCIM only** when provisioning must be fully controlled by your IdP's SCIM app and login-time claim changes should never alter membership. Leave it on the default **SCIM and login claims** if users are also provisioned just-in-time on first login.

This maps to the `claimsSyncMode` config key (`both` or `scim`) and is inert when SCIM is disabled - claims always sync then.

***

## Step 2: Configure your IdP to push SCIM to Bifrost

The exact steps vary by provider. Most SCIM-capable IdPs follow this general pattern:

<Steps>
  <Step title="Find the SCIM or provisioning settings">
    In your IdP admin console, look for:

    * **Provisioning** tab on your application
    * **SCIM** settings in the application integration
    * **Outbound provisioning** or **User sync** settings
  </Step>

  <Step title="Enter the Bifrost SCIM endpoint and token">
    | Setting                         | Value                                                 |
    | ------------------------------- | ----------------------------------------------------- |
    | **SCIM Base URL / Tenant URL**  | The SCIM Endpoint URL from Step 1 - no trailing slash |
    | **Bearer Token / Secret Token** | The Provisioning Token from Step 1                    |
  </Step>

  <Step title="Test the connection">
    Most IdPs provide a **Test Connection** or **Verify Credentials** button. Click it to confirm Bifrost is reachable and the token is valid.
  </Step>

  <Step title="Enable provisioning operations">
    Enable the following operations if available:

    * **Create Users** - provision new users when added in the IdP
    * **Update User Attributes** - sync profile changes to Bifrost
    * **Deactivate Users** - suspend users when deactivated or deleted in the IdP
    * **Push Groups** - sync group memberships so Bifrost team mappings stay current
  </Step>
</Steps>

***

## Step 3: Assign users and groups

<Steps>
  <Step title="Assign users or groups to the application">
    In your IdP, assign the users or groups you want to provision into Bifrost. Only users within the provisioning scope are pushed.

    Changes - new assignments, deactivations, group membership updates - will reflect in Bifrost within the next provisioning cycle. Most IdPs offer an on-demand sync option for immediate provisioning.
  </Step>
</Steps>

***

## Step 4: Verify in Bifrost

Once provisioning is active, confirm everything is syncing correctly:

* **Governance → Users** - provisioned users and their assigned roles
* **Governance → Teams** - teams populated from pushed groups
* **Governance → Business Units** - business units resolved from group or attribute mappings

***

## Bifrost SCIM API reference

| Method   | Endpoint               | Description                      |
| -------- | ---------------------- | -------------------------------- |
| `GET`    | `/scim/v2/Users`       | List users                       |
| `GET`    | `/scim/v2/Users/{id}`  | Get a user                       |
| `POST`   | `/scim/v2/Users`       | Provision a new user             |
| `PUT`    | `/scim/v2/Users/{id}`  | Replace a user                   |
| `PATCH`  | `/scim/v2/Users/{id}`  | Update user attributes or status |
| `DELETE` | `/scim/v2/Users/{id}`  | Deprovision a user               |
| `GET`    | `/scim/v2/Groups`      | List groups                      |
| `GET`    | `/scim/v2/Groups/{id}` | Get a group                      |
| `POST`   | `/scim/v2/Groups`      | Create a group                   |
| `PUT`    | `/scim/v2/Groups/{id}` | Replace a group                  |
| `PATCH`  | `/scim/v2/Groups/{id}` | Update group members             |
| `DELETE` | `/scim/v2/Groups/{id}` | Delete a group                   |

All requests must include an `Authorization: Bearer <token>` header using the Provisioning Token.

***

## How sync works

**Real-time push** - your IdP pushes user and group changes to Bifrost immediately when they occur.

**OIDC session refresh** - every 15 minutes, Bifrost refreshes active OIDC sessions. If a user has been deactivated, their Bifrost session is terminated.

***

## Troubleshooting

**Test Connection fails** - verify the SCIM Base URL has no trailing slash and the token matches exactly what Bifrost generated. Rotate the token in Bifrost and update your IdP.

**Users are provisioned but have no role** - SCIM provisions the user record; role assignment comes from attribute mappings in the OIDC provider. Confirm your Attribute-to-Role mappings are set and the relevant claims appear in the JWT at login time.

**Groups are not syncing** - confirm group push is enabled in your IdP's provisioning settings. Some IdPs require groups to be enabled separately from user sync.

**`401 Unauthorized` from Bifrost SCIM endpoint** - the provisioning token is incorrect or has been rotated. Generate a new token in Bifrost (**Provider Configuration → Rotate Token**) and update your IdP.

**`409 Conflict` when provisioning a user** - the user already exists in Bifrost (provisioned via OIDC login). Bifrost will merge the records on the next PATCH request from your IdP.
