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

# SCIM Overview

> Allow enterprise customers to use SCIM to manage identity and access from a workforce IdP

export const member = "Represents an individual end user's account within a given Organization, uniquely identified within that Organization by their email address.";

export const scim = "System for Cross-Domain Identity Management: a protocol that allows IT Admins to manage identity and access from a workforce identity provider.";

**System for Cross-Domain Identity Management (SCIM)** allows IT Admins to make changes to their employee's identity information and access within their workforce IdP (i.e Okta), and have those changes **automatically propagated** out to all of their connected applications. <Tooltip tip={scim}>SCIM</Tooltip> is critical for large enterprises, who rely on this protocol as a way to centrally and securely manage employee identity and access the thousands of SaaS tools companies use at scale.

<Columns cols={3}>
  <Card title="API Reference" href="/api-reference/b2b/api/scim/overview" icon="code">
    Use the SCIM API endpoints to manage SCIM connections on your backend.
  </Card>

  <Card title="Frontend SDKs" href="/api-reference/b2b/frontend-sdks/react/prebuilt-ui/admin-portal/scim" icon="compass">
    Use the frontend SDKs to manage SCIM connections on your frontend.
  </Card>

  <Card title="SCIM Admin Portal Component" href="/multi-tenant-auth/enterprise-ready/admin-portal" icon="grid-2x2-check">
    Add drop-in SCIM connection management UI to your application.
  </Card>
</Columns>

## How it works

Stytch's SCIM product handles everything out-of-the-box for you, immediately updating <Tooltip tip={member}>Members</Tooltip>, handling session revocation, and granting/revoking RBAC roles based on actions from the IdP.

To keep other systems in sync, use Stytch's [webhooks](/resources/workspace-management/webhooks) to trigger updates elsewhere in your application.

### Example flow

```mermaid theme={null}
sequenceDiagram
  participant IdP as Workforce IdP
  participant Stytch
  participant App as Your App

  Note over IdP: User is deprovisioned<br/>in the Organization's IdP
  IdP->>Stytch: Sends SCIM request<br/>communicating the change
  Note over Stytch: Updates Member status<br/>to deactivated,<br/>Revokes all sessions
  Stytch->>App: Triggers `scim.member.delete`<br/>webhook
  Note over App: [Optional] Receive<br/>webhook and make any<br/>necessary updates to your<br/>internal records
```

## Supported SCIM actions

The follow actions in SCIM are supported, and result in the following updates to the corresponding Stytch Organization and Members:

| SCIM action                   | Stytch updates                                          | RBAC updates                                                                         | Session updates                                                  | Webhook triggered               |
| ----------------------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------ | ---------------------------------------------------------------- | ------------------------------- |
| **Member provisioned**        | Creates Member in Organization                          | Assigns any email domain Implicit Role Grants                                        | scim.member.create                                               |                                 |
| **Member info updated**       | Update Member entity                                    | Revokes or Assigns any email domain Implicit Role Grants                             | RBAC changes propagated to active JWTs on next refresh \<= 5 min | `scim.member.update`            |
| **Member deprovisioned**      | Updates Member.Status to deactivated                    | Revokes all current Roles                                                            | Revokes all current Sessions                                     | `scim.member.delete`            |
| **Member reactivated**        | Updates Member.Status to active                         | Apply any qualified Implicit Role Grants (Explicit Roles Grants must be re-assigned) | `scim.member.update`                                             |                                 |
| **Group created**             | Creates a SCIM Group record with a stable UUID          | `scim.scim_group.create`                                                             |                                                                  |                                 |
| **Group info updated**        | Updates SCIM Group's Display Name (only editable field) | `scim.scim_group.update`                                                             |                                                                  |                                 |
| **Member added to group**     | Creates record of MemberID belonging to SCIM Group      | Applies any SCIM Group Implicit Role Grants                                          | RBAC changes propagated to active JWTs on next refresh \<= 5 min | `scim.scim_member_group.create` |
| **Member removed from group** | Sets Member's SCIM Group membership record to deleted   | Removes any SCIM Group Implicit Role Grants                                          | RBAC changes propagated to active JWTs on next refresh \<= 5 min | `scim.scim_member_group.delete` |
| **Group deleted**             | Updates SCIM Group and membership records to deleted    | Revokes any SCIM Group Implicit Role Grants                                          | RBAC changes propagated to active JWTs on next refresh \<= 5 min | `scim.scim_group.delete`        |

## Attribute mappings

Stytch requires any identity provider to specify the email and name of the member attempting to log in. It parses these from the attributes sent in the IdP's assertion to Stytch. To recognize which attributes correspond to which fields, Stytch allows your connection to define an `attribute_mapping`.

An example `attribute_mapping` looks like this:

```json theme={null}
{
  "email": "EmailAddress",
  "full_name": "FullName",
  "idp_user_id": "ExternalID",
  "title": "Title",
}
```

Stytch requires an `email` key to be present to determine the member's email. If the connection uses the Email Address NameID format, set the email key to NameID to tell Stytch to parse the `email` from the `NameID`. If the connection uses an alternative `NameID` format, set `email` to the value of the SAML attribute containing the member's email. Additionally, in order to determine the member's name, Stytch requires either the `full_name` key to be present, or both the `first_name` and `last_name` keys.

<Info>
  We **strongly recommend** configuring an `idp_user_id` attribute, set to the user's stable ID in their IdP. This will allow Stytch to find the existing Member in the event of an IdP-driven email change, and log the user into their existing account rather than creating a new Member record.
</Info>

Stytch reserves the following Attribute Mapping keys for internal use:

* `email`
* `full_name`
* `first_name`
* `last_name`
* `groups`
* `idp_user_id`

Any additional Custom Attribute Mappings defined will be used to promote SSO Attributes to the member's Trusted Metadata. Custom SSO Attributes will be merged with the member's existing Trusted Metadata using Stytch's [metadata update behavior.](/api-reference/b2b/api/resources/object-update-behavior)

### Considerations for using SSO Custom Attributes

* Although Trusted Metadata can still be updated directly via the [Update Member](/api-reference/b2b/api/members/update-member) endpoint, fields driven by the IdP will be overwritten again on subsequent logins.
* Metadata derived from IdP attributes will still exist after the IdP is deleted.
* If an IdP does NOT send a field, or the field is removed from the attribute mapping, Stytch will NOT delete the field from the Trusted Metadata on next login. All fields need to be deleted explicitly via the [Update Member](/api-reference/b2b/api/members/update-member) endpoint.

Putting this all together, given the following SAML assertion:

```yaml theme={null}
<saml2:AttributeStatement xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
    <saml2:Attribute Name="EmailAddress"
                     NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
        <saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
                              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">john.doe@example.com
        </saml2:AttributeValue>
    </saml2:Attribute>
    <saml2:Attribute Name="FullName"
                     NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
        <saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
                              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">John Doe
        </saml2:AttributeValue>
    </saml2:Attribute>
    <saml2:Attribute Name="ExternalID"
                     NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
        <saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
                              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">u_123_example
        </saml2:AttributeValue>
    </saml2:Attribute>
    <saml2:Attribute Name="Title"
                     NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
        <saml2:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
                              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Staff Software Engineer
        </saml2:AttributeValue>
    </saml2:Attribute>
</saml2:AttributeStatement>
```

Stytch will extract the following values:

* `member.email`: [john.doe@example.com](mailto:john.doe@example.com)
* `member.name`: John Doe
* `member.sso_registrations[0].external_id`: u\_123\_example
* `member.trusted_metadata.title`: Staff Software Engineer

The attribute mapping can be set in the [Update SAML Connection](/api-reference/b2b/api/sso/saml/update-saml-connection) endpoint.

### Single sign-on URLs

Some IdPs may ask for a single sign-on URL. This is listed as the `acs_url` in the [SAML connection object](/api-reference/b2b/api/sso/saml-connection-object). Note that for Stytch's purposes, the `acs_url` and `audience_uri` are the same value.
