> ## Documentation Index
> Fetch the complete documentation index at: https://wb-21fd5541-docs-hivemind-launch.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# SCIM으로 Users, 그룹, 역할 관리

> SCIM API를 사용해 자동 프로비저닝으로 W&B 조직의 Users, 그룹, 커스텀 역할을 관리하세요.

<Note>
  [SCIM이 작동하는 모습을 보여주는 비디오](https://www.youtube.com/watch?v=Nw3QBqV0I-o)를 시청하세요 (12분)
</Note>

<div id="overview">
  ## 개요
</div>

이 페이지에서는 인스턴스 관리자와 조직 관리자가 W\&B에서 ID 관리를 자동화하기 위해 SCIM(System for Cross-domain Identity Management) API를 사용하는 방법을 설명합니다. SCIM API를 사용하면 W\&B App에서 직접 클릭해 작업하는 대신, ID 공급자 또는 CI/CD 파이프라인을 통해 사용자를 프로비저닝하거나 프로비저닝 해제하고, 팀 멤버십을 관리하며, 커스텀 역할을 프로그래밍 방식으로 정의할 수 있습니다. SCIM 그룹은 W\&B Teams에 매핑됩니다.

W\&B의 SCIM API는 Okta와 같은 ID 공급자와 호환됩니다. Okta 및 기타 ID 공급자의 SSO 설정에 대해서는 [SSO documentation](/ko/platform/hosting/iam/sso/)을 참조하세요.

SCIM API와 상호 작용하는 방법을 보여주는 실용적인 Python 예시는 [`wandb-scim`](https://github.com/wandb/examples/tree/master/wandb-scim) 저장소에서 확인하세요.

<div id="supported-features">
  ### 지원되는 특성
</div>

SCIM API는 다음 특성을 지원합니다:

* **필터링**: API는 `/Users` 및 `/Groups` 엔드포인트에 대한 필터링을 지원합니다.
* **PATCH 오퍼레이션**: 리소스를 부분적으로 업데이트하기 위한 `PATCH`를 지원합니다.
* **ETag 지원**: 충돌 감지를 위해 ETag를 사용한 조건부 업데이트입니다.
* **서비스 계정 인증**: 조직 서비스 계정은 API에 액세스할 수 있습니다.
* **서비스 계정 라이프사이클**: [팀 범위 및 조직 범위 서비스 계정](/ko/platform/hosting/iam/service-accounts)을 프로비저닝 및 프로비저닝 해제할 수 있습니다. **Multi-tenant Cloud**에서 지원되며, **Dedicated Cloud** 및 **Self-Managed** v0.81.0+에서도 지원됩니다.

<Note>
  여러 Enterprise [Multi-tenant Cloud](/ko/platform/hosting/hosting-options/multi_tenant_cloud) 조직의 관리자라면, API 키를 사용한 요청이 올바른 조직에 적용되도록 SCIM API 요청을 수신할 조직을 설정하세요. 프로필 이미지를 클릭한 다음 **User Settings**를 클릭하고 **Default API organization** 설정을 확인하세요.

  선택한 호스팅 옵션에 따라 이 페이지의 예시에서 사용되는 `[HOST-URL]` 플레이스홀더 값이 결정됩니다.

  예시에서는 `abc` 및 `def`와 같은 사용자 ID를 사용합니다. 실제 요청과 응답에서는 사용자 ID에 해시된 값이 사용됩니다.
</Note>

<div id="authentication">
  ## 인증
</div>

모든 SCIM 요청은 관리자 주체로 인증되어야 합니다. 조직 관리자는 **Bearer 토큰** 또는 **HTTP Basic** 자격 증명을 사용해 인증할 수 있습니다. 두 방식 모두 키를 사용하는 경우 *같은 API 키 문자열* 을 사용합니다. 다음 섹션의 주요 차이를 검토한 후 사용자 ID 또는 조직 범위 서비스 계정을 선택하세요.

<div id="key-differences">
  ### 주요 차이점
</div>

다음 목록은 SCIM 인증을 위한 사용자 자격 증명과 서비스 계정 자격 증명을 비교합니다.

* 누가 사용해야 하나요: 사용자는 대화형의 일회성 관리자 액션에 가장 적합하며, 서비스 계정은 자동화 및 인테그레이션(CI/CD, 프로비저닝 도구)에 가장 적합합니다.
* 자격 증명: 사용자는 Basic 인증에 사용자 이름과 API 키를 함께 전송하고, 서비스 계정은 Basic 인증에 API 키만 전송합니다(사용자 이름 없음). Bearer 인증의 경우 헤더에 API 키만 전송하세요(사용자 이름 없음).
* Bearer와 Basic의 차이: Bearer는 키를 그대로 사용해 `Authorization: Bearer [API-KEY]` 형식을 사용합니다. Basic은 `Authorization: Basic <base64(...)>` 형식을 사용합니다(사용자는 `username:API-KEY`를 인코딩하고, 서비스 계정은 앞에 콜론을 붙이고 사용자 이름을 비운 `:API-KEY`를 인코딩합니다).
* 범위 및 권한: 인스턴스 또는 조직 관리자 사용자의 API 키나 [조직 범위 서비스 계정](/ko/platform/hosting/iam/service-accounts/#organization-scoped-service-accounts)의 API 키를 사용하세요. [팀 범위 서비스 계정](/ko/platform/hosting/iam/service-accounts/#team-scoped-service-accounts)의 키는 SCIM API에 인증할 수 없습니다. SCIM을 사용하는 서비스 계정은 조직 범위의 헤드리스 계정이므로, 자동화에 대해 더 명확한 감사 추적을 제공합니다.
* 자격 증명을 가져오는 위치: 사용자는 User Settings에서 자신의 API 키를 복사합니다. 조직 범위 서비스 계정 키는 조직 대시보드의 **Service account** 탭 아래에 있습니다.
* Multi-tenant Cloud: 둘 이상의 Multi-tenant Cloud 조직에 액세스할 수 있는 경우, SCIM API 호출이 의도한 조직으로 라우팅되도록 Default API organization을 설정해야 합니다.

<div id="bearer-token">
  ### Bearer 토큰
</div>

API 키를 Bearer 토큰 형식으로 전송하세요:

```bash theme={null}
Authorization: Bearer [API-KEY]
```

`[API-KEY]` 값은 해당 주체의 HTTP Basic 인증에서 비밀번호로 사용하는 문자열과 같습니다. Bearer 요청에는 키를 Base64로 인코딩하지 마세요.

<Note>
  SCIM API용 Bearer 인증은 W\&B Multi-tenant Cloud에서 사용 가능하며, Dedicated Cloud 및 Self-Managed v0.79.0 이상에서도 사용할 수 있습니다.
</Note>

다음 예시에서는 `[API-KEY]`를 플레이스홀더로 사용합니다. 이를 관리자 사용자 또는 조직 범위 서비스 계정의 실제 키로 교체하세요.

**사용자 목록**

```bash theme={null}
curl -s -S \
  -H "Authorization: Bearer [API-KEY]" \
  -H "Content-Type: application/scim+json" \
  "[HOST-URL]/scim/Users"
```

**사용자 생성**

```bash theme={null}
curl -s -S -X POST \
  -H "Authorization: Bearer [API-KEY]" \
  -H "Content-Type: application/scim+json" \
  "[HOST-URL]/scim/Users" \
  -d '{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
    "userName": "dev-user2",
    "emails": [{"primary": true, "value": "dev-user2@example.com"}]
  }'
```

자세한 내용은 [사용자 생성](#create-user)을 참조하세요.

<div id="users">
  ### Users
</div>

대화형 관리자 작업을 수행할 때는 개인 관리자 자격 증명을 사용하세요. HTTP `Authorization` 헤더는 `Basic <base64(username:API-KEY)>` 형식으로 만드세요.

예를 들어, `demo:p@55w0rd`로 인증합니다:

```bash theme={null}
Authorization: Basic ZGVtbzpwQDU1dzByZA==
```

<div id="service-accounts">
  ### 서비스 계정
</div>

자동화 또는 인테그레이션에는 조직 범위의 서비스 계정을 사용하세요. HTTP `Authorization` 헤더는 `Basic <base64(:API-KEY)>` 형식으로 구성합니다(앞의 콜론과 비어 있는 사용자 이름에 유의하세요). 서비스 계정 API 키는 조직 대시보드의 **Service account** 탭에서 찾을 수 있습니다. [조직 범위 서비스 계정](/ko/platform/hosting/iam/service-accounts/#organization-scoped-service-accounts)을 참고하세요.

예를 들어, API 키 `sa-p@55w0rd`를 사용해 인증합니다:

```bash theme={null}
Authorization: Basic OnNhLXBANTV3MHJk
```

<div id="user-management">
  ## 사용자 관리
</div>

SCIM 사용자 리소스는 W\&B 사용자와 서비스 계정에 매핑됩니다. 이 섹션의 엔드포인트를 사용하여 조직의 사용자와 서비스 계정을 프로비저닝, 업데이트, 제거하세요. 예를 들어 신규 직원을 온보딩할 때, 서비스 자격 증명을 교체할 때, 또는 퇴사하는 사용자의 액세스를 제거할 때 사용할 수 있습니다.

서비스 계정 개념과 UI 워크플로는 [서비스 계정을 사용해 워크플로 자동화하기](/ko/platform/hosting/iam/service-accounts)를 참조하세요.

<Note>
  **SCIM User JSON을 파싱하는 인테그레이션에 영향을 주는 호환성 깨짐 변경 사항**

  * Dedicated Cloud 및 Self-Managed v0.80.1+에서는, 그리고 Multi-tenant Cloud deployment에서는 2026년 4월 30일 이후 `/scim/Users` 응답(`GET` user, `GET` users, 그리고 User를 반환하는 `PATCH` 응답 포함)이 SCIM 2.0에 맞게 `emails`를 소문자 필드 이름(`value`, `primary`, 그리고 선택 항목인 `type` 또는 `display`)을 사용하는 객체의 JSON 배열로 직렬화합니다.
  * 이전 릴리스의 deployment에서는 `emails`를 PascalCase 키(`Value`, `Primary` 등)를 사용하는 단일 JSON 객체로 반환합니다.

  코드에서 SCIM *response* 의 `emails`를 읽는다면, `emails`를 배열로 처리하고 기본 항목(또는 첫 번째 요소)을 읽으세요.

  사용자 생성 또는 업데이트 요청 본문은 이미 배열 형식을 사용하고 있으므로 변경되지 않습니다. `list-users` 필터 `emails.value eq "..."`도 그대로 유지됩니다.
</Note>

<div id="get-user">
  ### 사용자 조회
</div>

사용자 ID를 사용해 조직 내 특정 사용자 또는 서비스 계정 정보를 조회하거나, 이메일 주소를 사용해 사용자 정보를 조회합니다.

서비스 계정 응답에는 `accountType`이 포함됩니다(`SERVICE`는 팀 범위 서비스 계정, `ORG_SERVICE`는 조직 범위 서비스 계정). 서비스 계정에는 `emails`가 포함되지 않습니다.

#### 엔드포인트

* **URL**: `[HOST-URL]/scim/Users/{id}`
* **방법**: `GET`

<div id="parameters">
  #### 매개변수
</div>

| 매개변수 | 유형     | 필수 | 설명         |
| ---- | ------ | -- | ---------- |
| `id` | string | 예  | 사용자의 고유 ID |

<div id="examples">
  #### 예시
</div>

<Tabs>
  <Tab title="사용자 조회 요청">
    ```bash theme={null}
    GET /scim/Users/abc
    ```
  </Tab>

  <Tab title="사용자 조회 응답">
    ```text theme={null}
    (Status 200)
    ```

    ```json theme={null}
    {
        "active": true,
        "daysActive": 42,
        "displayName": "Dev User 1",
        "emails": [
            {
                "primary": true,
                "value": "dev-user1@example.com"
            }
        ],
        "id": "abc",
        "lastActiveAt": "2023-10-15T14:32:10Z",
        "meta": {
            "resourceType": "User",
            "created": "2023-10-01T00:00:00Z",
            "lastModified": "2023-10-01T00:00:00Z",
            "location": "Users/abc"
        },
        "schemas": [
            "urn:ietf:params:scim:schemas:core:2.0:User"
        ],
        "userName": "dev-user1"
    }
    ```

    응답에는 조직 내 사용자 활동에 대한 세부 정보가 포함됩니다:

    * **`daysActive`**: 사용자가 조직에서 활동한 총 일수입니다.
    * **`lastActiveAt`**: 사용자의 가장 최근 활동 시점을 나타내는 ISO 8601 타임스탬프입니다. 사용자가 활동한 적이 없으면 `null`을 반환합니다.

    "active"의 정의는 배포 유형에 따라 다릅니다:

    * **Dedicated Cloud / Self-Managed**: 사용자가 로그인하거나, W\&B App의 페이지를 열거나, run을 로깅하거나, SDK를 사용하거나, 어떤 방식으로든 W\&B Server와 상호작용하면 active 상태로 간주됩니다.
    * **Multi-tenant Cloud**: 사용자가 2025년 5월 8일 이후 조직 범위에서 감사 가능한 작업을 수행하면 active 상태로 간주됩니다. 전체 목록은 [Audit logging actions](/ko/platform/hosting/monitoring-usage/audit-logging#actions)을 참조하세요.
  </Tab>
</Tabs>

<div id="list-users">
  ### Users 목록
</div>

조직의 모든 Users 및 서비스 계정 목록을 조회합니다. 각 리소스에는 `accountType`(`USER`, `SERVICE` 또는 `ORG_SERVICE`) 값이 포함됩니다.

<div id="filter-users">
  #### Users 필터링
</div>

`/Users` 엔드포인트는 사용자 이름이나 이메일 주소를 기준으로 사용자를 필터링할 수 있습니다:

* `userName eq "value"`: 사용자 이름으로 필터링.
* `emails.value eq "value"`: 이메일 주소로 필터링.

<div id="example">
  ##### 예시
</div>

```bash theme={null}
GET /scim/Users?filter=userName eq "john.doe"
GET /scim/Users?filter=emails.value eq "john@example.com"
```

#### 엔드포인트

* **URL**: `[HOST-URL]/scim/Users`
* **방법**: `GET`

<div id="examples">
  #### 예시
</div>

<Tabs>
  <Tab title="Users 목록 요청">
    ```bash theme={null}
    GET /scim/Users
    ```
  </Tab>

  <Tab title="Users 목록 응답">
    ```text theme={null}
    (Status 200)
    ```

    ```json theme={null}
    {
        "Resources": [
            {
                "active": true,
                "daysActive": 42,
                "displayName": "Dev User 1",
                "emails": [
                    {
                        "primary": true,
                        "value": "dev-user1@example.com"
                    }
                ],
                "id": "abc",
                "lastActiveAt": "2023-10-15T14:32:10Z",
                "meta": {
                    "resourceType": "User",
                    "created": "2023-10-01T00:00:00Z",
                    "lastModified": "2023-10-01T00:00:00Z",
                    "location": "Users/abc"
                },
                "schemas": [
                    "urn:ietf:params:scim:schemas:core:2.0:User"
                ],
                "userName": "dev-user1"
            }
        ],
        "itemsPerPage": 9999,
        "schemas": [
            "urn:ietf:params:scim:api:messages:2.0:ListResponse"
        ],
        "startIndex": 1,
        "totalResults": 1
    }
    ```

    응답에는 조직 내 각 사용자의 활동에 대한 세부 정보가 포함됩니다:

    * **`daysActive`**: 사용자가 조직에서 활동한 총 일수입니다.
    * **`lastActiveAt`**: 사용자의 가장 최근 활동 시각을 나타내는 ISO 8601 타임스탬프입니다. 사용자가 활동하지 않았다면 `null`을 반환합니다.

    "active"의 정의는 배포 유형에 따라 다릅니다:

    * **Dedicated Cloud / Self-Managed**: 사용자가 로그인하거나, W\&B App에서 페이지를 하나라도 열거나, run을 로깅하거나, SDK를 사용하거나, 어떤 방식으로든 W\&B Server와 상호작용하면 active 상태로 간주됩니다.
    * **Multi-tenant Cloud**: 사용자가 2025년 5월 8일 이후 조직 범위에서 감사 가능한 작업을 수행하면 active 상태로 간주됩니다. 전체 목록은 [Audit logging actions](/ko/platform/hosting/monitoring-usage/audit-logging#actions)을 참조하세요.
  </Tab>
</Tabs>

<div id="create-user">
  ### 사용자 생성
</div>

조직에 새 사용자를 추가합니다.

#### 엔드포인트

* **URL**: `[HOST-URL]/scim/Users`
* **방법**: `POST`

<div id="parameters">
  #### 매개변수
</div>

| 매개변수         | 유형     | 필수  | 설명                                                                 |
| ------------ | ------ | --- | ------------------------------------------------------------------ |
| `emails`     | 배열     | 예   | 이메일 객체 배열입니다. 기본 이메일이 포함되어야 합니다.                                   |
| `userName`   | string | 예   | 새로 생성할 사용자의 사용자 이름입니다.                                             |
| `modelsSeat` | string | 아니요 | Models 시트 수준입니다. `full`, `viewer`, `none` 중 하나입니다. 기본값은 `full`입니다. |
| `weaveRole`  | string | 아니요 | Weave 역할 수준입니다. `full`, `viewer`, `none` 중 하나입니다. 기본값은 `full`입니다.  |

<div id="examples">
  #### 예시
</div>

<Tabs>
  <Tab title="사용자 생성 요청 (Dedicated/Self-Managed)">
    ```bash theme={null}
    POST /scim/Users
    ```

    ```json theme={null}
    {
        "schemas": [
            "urn:ietf:params:scim:schemas:core:2.0:User"
        ],
        "emails": [
            {
                "primary": true,
                "value": "dev-user2@example.com"
            }
        ],
        "userName": "dev-user2",
        "modelsSeat": "full",
        "weaveRole": "full"
    }
    ```
  </Tab>

  <Tab title="사용자 생성 요청 (Multi-tenant)">
    ```bash theme={null}
    POST /scim/Users
    ```

    ```json theme={null}
    {
        "schemas": [
            "urn:ietf:params:scim:schemas:core:2.0:User",
            "urn:ietf:params:scim:schemas:extension:teams:2.0:User"
        ],
        "emails": [
            {
                "primary": true,
                "value": "dev-user2@example.com"
            }
        ],
        "userName": "dev-user2",
        "modelsSeat": "full",
        "weaveRole": "full",
        "urn:ietf:params:scim:schemas:extension:teams:2.0:User": {
            "teams": ["my-team"]
        }
    }
    ```
  </Tab>
</Tabs>

<div id="response">
  #### 응답
</div>

<Tabs>
  <Tab title="사용자 생성 응답 (Dedicated/Self-Managed)">
    ```text theme={null}
    (Status 201)
    ```

    ```json theme={null}
    {
        "active": true,
        "displayName": "Dev User 2",
        "emails": [
            {
                "primary": true,
                "value": "dev-user2@example.com"
            }
        ],
        "id": "def",
        "meta": {
            "resourceType": "User",
            "created": "2023-10-01T00:00:00Z",
            "location": "Users/def"
        },
        "schemas": [
            "urn:ietf:params:scim:schemas:core:2.0:User"
        ],
        "modelsSeat": "full",
        "weaveRole": "full",
        "userName": "dev-user2"
    }
    ```
  </Tab>

  <Tab title="사용자 생성 응답 (Multi-tenant)">
    ```text theme={null}
    (Status 201)
    ```

    ```json theme={null}
    {
        "active": true,
        "displayName": "Dev User 2",
        "emails": [
            {
                "primary": true,
                "value": "dev-user2@example.com"
            }
        ],
        "id": "def",
        "meta": {
            "resourceType": "User",
            "created": "2023-10-01T00:00:00Z",
            "location": "Users/def"
        },
        "schemas": [
            "urn:ietf:params:scim:schemas:core:2.0:User",
            "urn:ietf:params:scim:schemas:extension:teams:2.0:User"
        ],
        "userName": "dev-user2",
        "organizationRole": "member",
        "modelsSeat": "full",
        "weaveRole": "full",
        "teamRoles": [
            {
                "teamName": "my-team",
                "roleName": "member"
            }
        ],
        "groups": [
            {
                "value": "my-team-id"
            }
        ]
    }
    ```
  </Tab>
</Tabs>

<div id="provision-service-account">
  ### 서비스 계정 프로비저닝
</div>

조직에서 팀 범위 또는 조직 범위의 서비스 계정을 생성합니다. 이 엔드포인트를 사용하여 사람 사용자에 연결되지 않아야 하는 자동화, CI/CD 또는 인테그레이션용 헤드리스 ID를 생성하세요. 대신 일반 사용자를 생성하려면 `accountType`을 생략하세요. [사용자 생성](#create-user)을 참조하세요.

<Note>
  **Dedicated Cloud** 및 **Self-Managed** v0.81.0+와 **Multi-tenant Cloud**에서 사용 가능합니다.

  * `userName`을 서비스 계정 이름으로 설정하세요. API는 계정의 표시 이름으로 `userName`을 사용하며, 요청 본문의 `displayName`은 무시됩니다.
  * 서비스 계정에는 `emails`가 필요하지 않습니다.
  * 생성 시 `modelsSeat` 및 `weaveRole`은 지원되지 않으며, 포함되어 있으면 `400 Bad Request`가 반환됩니다.
  * 서비스 계정은 `PATCH` 또는 `PUT`으로 업데이트할 수 없고, 비활성화할 수도 없으며, SCIM을 통해 조직, 팀 또는 레지스트리 역할을 부여할 수도 없습니다. 프로비저닝 후 W\&B App에서 API 키를 생성하세요.
</Note>

#### 엔드포인트

* **URL**: `[HOST-URL]/scim/Users`
* **방법**: `POST`

<div id="parameters">
  #### 매개변수
</div>

| 매개변수                                                    | 유형     | 필수  | 설명                                                                                                                                                                                                                           |
| ------------------------------------------------------- | ------ | --- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `userName`                                              | string | 예   | 서비스 계정의 고유한 이름입니다.                                                                                                                                                                                                           |
| `accountType`                                           | string | 예   | [팀 범위 서비스 계정](/ko/platform/hosting/iam/service-accounts/#team-scoped-service-accounts)에는 `SERVICE`를, [조직 범위 서비스 계정](/ko/platform/hosting/iam/service-accounts/#organization-scoped-service-accounts)에는 `ORG_SERVICE`를 사용합니다. |
| `urn:ietf:params:scim:schemas:extension:teams:2.0:User` | object | 예   | Teams 확장 객체입니다.                                                                                                                                                                                                              |
| `defaultTeam`                                           | string | 예   | Teams 확장의 하위 필드입니다. 기존 W\&B Team의 이름입니다. 서비스 계정은 이 팀의 멤버로 생성됩니다. 팀 범위 서비스 계정은 이 팀에만 속합니다. 조직 범위 서비스 계정은 이후 SCIM을 통해 생성되는 팀에도 자동으로 추가됩니다.                                                                                     |
| `teams`                                                 | array  | 아니요 | **Multi-tenant Cloud에서만 사용합니다.** 계정을 추가할 팀 이름 목록입니다. 이 필드를 사용할 때는 `defaultTeam`과 동일한 팀도 포함하세요.                                                                                                                               |

<div id="examples">
  #### 예시
</div>

<Tabs>
  <Tab title="팀 서비스 계정 프로비저닝 요청">
    ```bash theme={null}
    POST /scim/Users
    ```

    ```json theme={null}
    {
        "schemas": [
            "urn:ietf:params:scim:schemas:core:2.0:User",
            "urn:ietf:params:scim:schemas:extension:teams:2.0:User"
        ],
        "userName": "sa-deploy-bot",
        "accountType": "SERVICE",
        "urn:ietf:params:scim:schemas:extension:teams:2.0:User": {
            "defaultTeam": "ml-platform"
        }
    }
    ```
  </Tab>

  <Tab title="조직 서비스 계정 프로비저닝 요청">
    ```bash theme={null}
    POST /scim/Users
    ```

    ```json theme={null}
    {
        "schemas": [
            "urn:ietf:params:scim:schemas:core:2.0:User",
            "urn:ietf:params:scim:schemas:extension:teams:2.0:User"
        ],
        "userName": "sa-ci-runner",
        "accountType": "ORG_SERVICE",
        "urn:ietf:params:scim:schemas:extension:teams:2.0:User": {
            "defaultTeam": "ml-platform"
        }
    }
    ```
  </Tab>
</Tabs>

<div id="response">
  #### 응답
</div>

<Tabs>
  <Tab title="팀 서비스 계정 프로비저닝 응답">
    ```text theme={null}
    (Status 201)
    ```

    ```json theme={null}
    {
        "accountType": "SERVICE",
        "active": true,
        "displayName": "sa-deploy-bot",
        "id": "xyz",
        "meta": {
            "resourceType": "User",
            "created": "2023-10-01T00:00:00Z",
            "location": "Users/xyz"
        },
        "organizationRole": "member",
        "schemas": [
            "urn:ietf:params:scim:schemas:core:2.0:User",
            "urn:ietf:params:scim:schemas:extension:wandb:2.0:User"
        ],
        "teamRoles": [
            {
                "teamName": "ml-platform",
                "roleName": "member"
            }
        ],
        "urn:ietf:params:scim:schemas:extension:wandb:2.0:User": {
            "organizationRole": "member"
        },
        "userName": "sa-deploy-bot"
    }
    ```
  </Tab>

  <Tab title="조직 서비스 계정 프로비저닝 응답">
    ```text theme={null}
    (Status 201)
    ```

    ```json theme={null}
    {
        "accountType": "ORG_SERVICE",
        "active": true,
        "displayName": "sa-ci-runner",
        "id": "xyz",
        "meta": {
            "resourceType": "User",
            "created": "2023-10-01T00:00:00Z",
            "location": "Users/xyz"
        },
        "organizationRole": "member",
        "schemas": [
            "urn:ietf:params:scim:schemas:core:2.0:User",
            "urn:ietf:params:scim:schemas:extension:wandb:2.0:User"
        ],
        "teamRoles": [
            {
                "teamName": "ml-platform",
                "roleName": "member"
            }
        ],
        "urn:ietf:params:scim:schemas:extension:wandb:2.0:User": {
            "organizationRole": "member"
        },
        "userName": "sa-ci-runner"
    }
    ```
  </Tab>
</Tabs>

조직 범위 서비스 계정의 경우 `accountType`은 `ORG_SERVICE`입니다.

**Self-Managed** 배포 환경에서는 `organizationRole`이 계정 유형에 맞게 `member`가 아니라 `service` 또는 `org_service`로 반환됩니다.

응답에서 다음 오류 중 하나가 반환되면 요청에 아래와 같은 일반적인 문제가 있는지 확인하세요.

* `409 Conflict`: 요청에 동일한 서비스 계정에 대해 중복된 `userName` 키가 포함되어 있습니다.
* `400 Bad Request`: 요청에 `defaultTeam`이 누락되었거나 잘못된 값으로 설정되어 있습니다.

<div id="deprovision-service-account">
  ### 서비스 계정 프로비저닝 해제
</div>

서비스 계정과 해당 조직 멤버십을 영구 삭제합니다. 서비스 계정이 더 이상 필요하지 않을 때(예: 자동화 파이프라인을 종료한 후) 이 엔드포인트를 사용하세요. 이는 하드 삭제이므로 SCIM을 통해 계정을 다시 활성화할 수 없습니다.

<Note>
  **Dedicated Cloud**, **Self-Managed** v0.81.0+ 및 **Multi-tenant Cloud**에서 사용 가능합니다. 프로비저닝 응답 또는 [사용자 조회](#get-user)에서 서비스 계정의 SCIM 사용자 `id`를 사용하세요. 프로비저닝을 해제해도 이미 발급된 API 키는 삭제되지 않으므로, 필요한 경우 W\&B App에서 키를 별도로 폐기하세요.
</Note>

#### 엔드포인트

* **URL**: `[HOST-URL]/scim/Users/{id}`
* **방법**: `DELETE`

<div id="parameters">
  #### 매개변수
</div>

| 매개변수 | 유형     | 필수 | 설명                |
| ---- | ------ | -- | ----------------- |
| `id` | string | 예  | 서비스 계정의 고유 ID입니다. |

<div id="examples">
  #### 예시
</div>

<Tabs>
  <Tab title="서비스 계정 프로비저닝 해제 요청">
    ```bash theme={null}
    DELETE /scim/Users/xyz
    ```
  </Tab>

  <Tab title="서비스 계정 프로비저닝 해제 응답">
    ```text theme={null}
    (Status 204)
    ```
  </Tab>
</Tabs>

<div id="delete-user">
  ### 사용자 삭제
</div>

<Warning>
  **관리자 액세스 유지**

  인스턴스 또는 조직에는 항상 최소 한 명의 관리자 사용자가 있어야 합니다. 그렇지 않으면 아무도 조직의 W\&B 계정을 설정하거나 관리할 수 없습니다. 조직에서 SCIM 또는 다른 자동화된 프로세스를 사용해 W\&B에서 사용자를 프로비저닝 해제하는 경우, 프로비저닝 해제 오퍼레이션으로 인해 인스턴스 또는 조직에 마지막으로 남아 있던 관리자가 의도치 않게 제거될 수 있습니다.

  운영 절차 수립에 도움이 필요하거나 관리자 액세스를 복구해야 하는 경우 [지원팀](mailto:support@wandb.com)에 문의하세요.
</Warning>

조직에서 사용자를 완전히 삭제합니다. 서비스 계정을 삭제하려면 [서비스 계정 프로비저닝 해제](#deprovision-service-account)를 참조하세요.

#### 엔드포인트

* **URL**: `[HOST-URL]/scim/Users/{id}`
* **방법**: `DELETE`

<div id="parameters">
  #### 매개변수
</div>

| 매개변수 | 유형     | 필수 | 설명             |
| ---- | ------ | -- | -------------- |
| `id` | string | 예  | 삭제할 사용자의 고유 ID |

<div id="examples">
  #### 예시
</div>

<Tabs>
  <Tab title="사용자 삭제 요청">
    ```bash theme={null}
    DELETE /scim/Users/abc
    ```
  </Tab>

  <Tab title="사용자 삭제 응답">
    ```text theme={null}
    (Status 204)
    ```
  </Tab>
</Tabs>

<Note>
  사용자를 일시적으로 비활성화하려면 `PATCH` 엔드포인트를 사용하는 [사용자 비활성화](#deactivate-user) API를 참고하세요.
</Note>

<div id="update-user-email">
  ### 사용자 이메일 업데이트
</div>

사용자의 기본 이메일 주소를 업데이트합니다.

**Multi-tenant Cloud에서는 지원되지 않습니다.** 이 환경에서는 사용자 계정을 조직에서 관리하지 않습니다.

#### 엔드포인트

* **URL**: `[HOST-URL]/scim/Users/{id}`
* **방법**: `PATCH`

<div id="parameters">
  #### 매개변수
</div>

| 매개변수    | 유형     | 필수 | 설명                |
| ------- | ------ | -- | ----------------- |
| `id`    | string | 예  | 사용자의 고유 ID        |
| `op`    | string | 예  | `replace`         |
| `path`  | string | 예  | `emails`          |
| `value` | array  | 예  | 새 이메일 객체를 포함하는 배열 |

<div id="examples">
  #### 예시
</div>

<Tabs>
  <Tab title="이메일 주소 업데이트 요청">
    ```bash theme={null}
    PATCH /scim/Users/abc
    ```

    ```json theme={null}
    {
        "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
        "Operations": [
            {
                "op": "replace",
                "path": "emails",
                "value": [
                    {
                        "value": "newemail@example.com",
                        "primary": true
                    }
                ]
            }
        ]
    }
    ```
  </Tab>

  <Tab title="이메일 주소 업데이트 응답">
    ```text theme={null}
    (Status 200)
    ```

    ```json theme={null}
    {
        "active": true,
        "displayName": "Dev User 1",
        "emails": [
            {
                "primary": true,
                "value": "newemail@example.com"
            }
        ],
        "id": "abc",
        "meta": {
            "resourceType": "User",
            "created": "2023-10-01T00:00:00Z",
            "lastModified": "2023-10-01T00:00:00Z",
            "location": "Users/abc"
        },
        "schemas": [
            "urn:ietf:params:scim:schemas:core:2.0:User"
        ],
        "userName": "dev-user1"
    }
    ```
  </Tab>
</Tabs>

<div id="update-user-display-name">
  ### 사용자 표시 이름 업데이트
</div>

사용자의 표시 이름을 업데이트합니다.

**Multi-tenant Cloud에서는 지원되지 않습니다.** 이 환경에서는 사용자의 계정을 조직이 관리하지 않습니다.

#### 엔드포인트

* **URL**: `[HOST-URL]/scim/Users/{id}`
* **방법**: `PATCH`

<div id="parameters">
  #### 매개변수
</div>

| 매개변수    | 유형     | 필수 | 설명            |
| ------- | ------ | -- | ------------- |
| `id`    | string | 예  | 사용자의 고유 ID    |
| `op`    | string | 예  | `replace`     |
| `path`  | string | 예  | `displayName` |
| `value` | string | 예  | 새 표시 이름       |

<div id="examples">
  #### 예시
</div>

<Tabs>
  <Tab title="표시 이름 업데이트 요청">
    ```bash theme={null}
    PATCH /scim/Users/abc
    ```

    ```json theme={null}
    {
        "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
        "Operations": [
            {
                "op": "replace",
                "path": "displayName",
                "value": "John Doe"
            }
        ]
    }
    ```
  </Tab>

  <Tab title="표시 이름 업데이트 응답">
    ```text theme={null}
    (Status 200)
    ```

    ```json theme={null}
    {
        "active": true,
        "displayName": "John Doe",
        "emails": [
            {
                "primary": true,
                "value": "dev-user1@example.com"
            }
        ],
        "id": "abc",
        "meta": {
            "resourceType": "User",
            "created": "2025-7-01T00:00:00Z",
            "lastModified": "2025-7-01T00:00:00Z",
            "location": "users/dev-user1"
        },
        "schemas": [
            "urn:ietf:params:scim:schemas:core:2.0:User"
        ],
        "userName": "dev-user1"
    }
    ```
  </Tab>
</Tabs>

<div id="deactivate-user">
  ### 사용자 비활성화
</div>

조직에서 사용자를 비활성화합니다. 결과는 배포 유형에 따라 다릅니다.

* **Dedicated Cloud** / **Self-Managed**: 사용자의 `active` 필드를 `false`로 설정합니다. 비활성화된 사용자의 조직 액세스 권한을 복원하려면 [사용자 재활성화](#reactivate-user)를 참조하세요.
* **Multi-tenant Cloud**: 조직에서 사용자를 제거합니다. 사용자의 액세스 권한을 복원하려면 해당 사용자를 조직에 다시 추가하세요. [사용자 생성](#create-user-request-multi-tenant)을 참조하세요. Multi-tenant Cloud에서는 사용자 계정을 조직에서 관리하지 않습니다.

<Note>이 오퍼레이션은 서비스 계정이 아니라 사용자에만 적용됩니다. 서비스 계정 비활성화는 지원되지 않습니다. W\&B Team의 Settings에서 팀 서비스 계정을 관리하세요.</Note>

#### 엔드포인트

* **URL**: `[HOST-URL]/scim/Users/{id}`
* **방법**: `PATCH`

<div id="parameters">
  #### 매개변수
</div>

| 매개변수    | 유형     | 필수 | 설명                     |
| ------- | ------ | -- | ---------------------- |
| `id`    | string | 예  | 비활성화할 사용자의 고유 ID       |
| `op`    | string | 예  | `replace`              |
| `value` | 객체     | 예  | `{"active": false}` 객체 |

<div id="examples">
  #### 예시
</div>

<Tabs>
  <Tab title="사용자 비활성화 요청 (Dedicated/Self-Managed)">
    ```bash theme={null}
    PATCH /scim/Users/abc
    ```

    ```json theme={null}
    {
        "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
        "Operations": [
            {
                "op": "replace",
                "value": {"active": false}
            }
        ]
    }
    ```
  </Tab>

  <Tab title="사용자 비활성화 요청 (Multi-tenant)">
    ```bash theme={null}
    PATCH /scim/Users
    ```

    ```json theme={null}
    {
        "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
        "Operations": [
            {
                "op": "replace",
                "value": {"active": false}
            }
        ]
    }
    ```
  </Tab>
</Tabs>

<div id="response">
  #### 응답
</div>

<Tabs>
  <Tab title="사용자 비활성화 응답 (Dedicated/Self-Managed)">
    ```text theme={null}
    (Status 200)
    ```

    ```json theme={null}
    {
        "active": false,
        "displayName": "Dev User 1",
        "emails": [
            {
                "primary": true,
                "value": "dev-user1@example.com"
            }
        ],
        "id": "abc",
        "meta": {
            "resourceType": "User",
            "created": "2023-10-01T00:00:00Z",
            "lastModified": "2023-10-01T00:00:00Z",
            "location": "Users/abc"
        },
        "schemas": [
            "urn:ietf:params:scim:schemas:core:2.0:User"
        ],
        "userName": "dev-user1"
    }
    ```
  </Tab>

  <Tab title="사용자 비활성화 응답 (Multi-tenant)">
    ```text theme={null}
    (Status 200)
    ```

    ```json theme={null}
    {
        "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
        "Operations": [
            {
                "op": "replace",
                "value": {"active": true}
            }
        ]
    }
    ```
  </Tab>
</Tabs>

<div id="reactivate-user">
  ### 사용자 재활성화
</div>

이전에 비활성화된 사용자를 조직에서 다시 활성화합니다.

<Note>
  * 사용자 재활성화는 사용자에게만 적용되며 서비스 계정에는 적용되지 않습니다. 서비스 계정 재활성화는 지원되지 않습니다. 서비스 계정은 W\&B Team의 Settings에서 관리하세요.

  * [Multi-tenant Cloud](/ko/platform/hosting/hosting-options/multi_tenant_cloud)에서는 사용자 재활성화를 지원하지 않습니다. 사용자의 액세스를 복원하려면 해당 사용자를 조직에 다시 추가하세요. [사용자 생성](#create-user-request-multi-tenant)을 참조하세요. Multi-tenant Cloud에서는 사용자 계정을 조직에서 관리하지 않습니다. 사용자를 재활성화하려고 하면 HTTP `400` 오류가 발생합니다. 응답 본문의 `detail` 필드는 API에서 원문 그대로 반환되므로, 이전 제품 용어를 계속 사용할 수 있습니다.
    ```json theme={null}
    {
        "schemas": [
            "urn:ietf:params:scim:api:messages:2.0:Error"
        ],
        "detail": "User reactivation operations are not supported in SaaS Cloud",
        "status": "400"
    }
    ```
</Note>

#### 엔드포인트

* **URL**: `[HOST-URL]/scim/Users/{id}`
* **방법**: `PATCH`

<div id="parameters">
  #### 매개변수
</div>

| 매개변수    | 유형     | 필수 | 설명                          |
| ------- | ------ | -- | --------------------------- |
| `id`    | string | 예  | 다시 활성화할 사용자의 고유 ID          |
| `op`    | string | 예  | `replace`                   |
| `value` | 객체     | 예  | `{"active": true}`를 포함하는 객체 |

<div id="examples">
  #### 예시
</div>

<Tabs>
  <Tab title="사용자 재활성화 요청">
    ```bash theme={null}
    PATCH /scim/Users/abc
    ```

    ```json theme={null}
    {
        "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
        "Operations": [
            {
                "op": "replace",
                "value": {"active": true}
            }
        ]
    }
    ```
  </Tab>

  <Tab title="사용자 재활성화 응답">
    ```text theme={null}
    (Status 200)
    ```

    ```json theme={null}
    {
        "active": true,
        "displayName": "Dev User 1",
        "emails": [
            {
                "primary": true,
                "value": "dev-user1@example.com"
            }
        ],
        "id": "abc",
        "meta": {
            "resourceType": "User",
            "created": "2023-10-01T00:00:00Z",
            "lastModified": "2023-10-01T00:00:00Z",
            "location": "Users/abc"
        },
        "schemas": [
            "urn:ietf:params:scim:schemas:core:2.0:User"
        ],
        "userName": "dev-user1"
    }
    ```
  </Tab>
</Tabs>

<div id="assign-organization-role">
  ### 조직 역할 부여
</div>

사용자에게 조직 수준의 역할을 할당합니다.

<Note>이 오퍼레이션은 서비스 계정이 아닌 사용자에게만 적용됩니다. 서비스 계정에는 커스텀 역할이 지원되지 않습니다.</Note>

#### 엔드포인트

* **URL**: `[HOST-URL]/scim/Users/{id}`
* **방법**: `PATCH`

<div id="parameters">
  #### 매개변수
</div>

| 매개변수    | 유형     | 필수 | 설명                         |
| ------- | ------ | -- | -------------------------- |
| `id`    | string | 예  | 사용자의 고유 ID                 |
| `op`    | string | 예  | `replace`                  |
| `path`  | string | 예  | `organizationRole`         |
| `value` | string | 예  | 역할 이름(`admin` 또는 `member`) |

<Note>
  조직 수준의 `viewer` 역할은 사용 중단되었으며 더 이상 UI에서 할당할 수 없습니다. SCIM을 사용해 사용자에게 `viewer` 역할을 할당하면:

  * 사용자는 조직에서 `member` 역할을 부여받습니다.
  * 해당 사용자의 `modelsSeat`는 `full` 대신 `viewer`로 설정됩니다. 그러면 Models에는 보기 전용 액세스가, 레지스트리에는 전체 액세스가 허용됩니다. 사용 가능한 Models 시트가 없으면 `Seat limit reached` 오류가 반환됩니다. 시트를 사용할 수 있게 되면 나중에 업데이트할 수 있습니다.
  * 해당 사용자의 `weaveRole`은 `full` 대신 `viewer`로 설정됩니다. 그러면 Weave에는 보기 전용 액세스가 허용됩니다.
  * 해당 사용자의 기존 팀 및 프로젝트 역할은 모두 `viewer`로 설정됩니다.
  * 조직 수준에서 볼 수 있는 레지스트리에서는 레지스트리 `viewer` 역할이 부여됩니다.

  `member` 또는 `admin` 조직 역할을 부여해도 사용자의 `modelsSeat` 또는 `weaveRole`은 변경되지 않습니다.
</Note>

<div id="examples">
  #### 예시
</div>

<Tabs>
  <Tab title="조직 역할 부여 요청">
    ```bash theme={null}
    PATCH /scim/Users/abc
    ```

    ```json theme={null}
    {
        "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
        "Operations": [
            {
                "op": "replace",
                "path": "organizationRole",
                "value": "admin"
            }
        ]
    }
    ```
  </Tab>

  <Tab title="조직 역할 부여 응답">
    ```text theme={null}
    (Status 200)
    ```

    ```json theme={null}
    {
        "active": true,
        "displayName": "Dev User 1",
        "emails": [
            {
                "primary": true,
                "value": "dev-user1@example.com"
            }
        ],
        "id": "abc",
        "meta": {
            "resourceType": "User",
            "created": "2023-10-01T00:00:00Z",
            "lastModified": "2023-10-01T00:00:00Z",
            "location": "Users/abc"
        },
        "schemas": [
            "urn:ietf:params:scim:schemas:core:2.0:User"
        ],
        "userName": "dev-user1",
        "teamRoles": [
            {
                "teamName": "team1",
                "roleName": "admin"
            }
        ],
        "organizationRole": "admin"
    }
    ```
  </Tab>
</Tabs>

<div id="update-models-seat">
  ### Models 시트 업데이트
</div>

사용자의 Models 시트를 업데이트합니다.

#### 엔드포인트

* **URL**: `[HOST-URL]/scim/Users/{id}`
* **방법**: `PATCH`

<div id="parameters">
  #### 매개변수
</div>

| 매개변수    | 유형     | 필수 | 설명                                |
| ------- | ------ | -- | --------------------------------- |
| `id`    | string | 예  | 사용자의 고유 ID                        |
| `op`    | string | 예  | `replace`                         |
| `path`  | string | 예  | `modelsSeat`                      |
| `value` | string | 예  | 시트 수준(`full`, `viewer` 또는 `none`) |

<div id="examples">
  #### 예시
</div>

<Tabs>
  <Tab title="Models 시트 업데이트 요청">
    ```bash theme={null}
    PATCH /scim/Users/abc
    ```

    ```json theme={null}
    {
        "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
        "Operations": [
            {
                "op": "replace",
                "path": "modelsSeat",
                "value": "full"
            }
        ]
    }
    ```
  </Tab>

  <Tab title="Models 시트 업데이트 응답">
    ```text theme={null}
    (Status 200)
    ```

    ```json theme={null}
    {
        "active": true,
        "displayName": "Dev User 1",
        "emails": [
            {
                "primary": true,
                "value": "dev-user1@example.com"
            }
        ],
        "id": "abc",
        "meta": {
            "resourceType": "User",
            "created": "2023-10-01T00:00:00Z",
            "lastModified": "2023-10-01T00:00:00Z",
            "location": "Users/abc"
        },
        "schemas": [
            "urn:ietf:params:scim:schemas:core:2.0:User"
        ],
        "userName": "dev-user1",
        "organizationRole": "member",
        "modelsSeat": "full",
        "weaveRole": "full"
    }
    ```
  </Tab>
</Tabs>

<div id="update-weave-role">
  ### Weave 역할 업데이트
</div>

사용자의 Weave 역할을 업데이트합니다.

#### 엔드포인트

* **URL**: `[HOST-URL]/scim/Users/{id}`
* **방법**: `PATCH`

<div id="parameters">
  #### 매개변수
</div>

| 매개변수    | 유형     | 필수 | 설명                                |
| ------- | ------ | -- | --------------------------------- |
| `id`    | string | 예  | 사용자의 고유 ID                        |
| `op`    | string | 예  | `replace`                         |
| `path`  | string | 예  | `weaveRole`                       |
| `value` | string | 예  | 역할 수준(`full`, `viewer` 또는 `none`) |

<div id="examples">
  #### 예시
</div>

<Tabs>
  <Tab title="Weave 역할 업데이트 요청">
    ```bash theme={null}
    PATCH /scim/Users/abc
    ```

    ```json theme={null}
    {
        "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
        "Operations": [
            {
                "op": "replace",
                "path": "weaveRole",
                "value": "full"
            }
        ]
    }
    ```
  </Tab>

  <Tab title="Weave 역할 업데이트 응답">
    ```text theme={null}
    (Status 200)
    ```

    ```json theme={null}
    {
        "active": true,
        "displayName": "Dev User 1",
        "emails": [
            {
                "primary": true,
                "value": "dev-user1@example.com"
            }
        ],
        "id": "abc",
        "meta": {
            "resourceType": "User",
            "created": "2023-10-01T00:00:00Z",
            "lastModified": "2023-10-01T00:00:00Z",
            "location": "Users/abc"
        },
        "schemas": [
            "urn:ietf:params:scim:schemas:core:2.0:User"
        ],
        "userName": "dev-user1",
        "organizationRole": "member",
        "modelsSeat": "full",
        "weaveRole": "full"
    }
    ```
  </Tab>
</Tabs>

<div id="assign-team-role">
  ### 팀 역할 할당
</div>

사용자에게 팀 수준의 역할을 할당합니다.

<Note>이 오퍼레이션은 서비스 계정이 아니라 사용자에게만 적용됩니다. 서비스 계정에서는 커스텀 역할이 지원되지 않습니다.</Note>

#### 엔드포인트

* **URL**: `[HOST-URL]/scim/Users/{id}`
* **방법**: `PATCH`

<div id="parameters">
  #### 매개변수
</div>

| 매개변수    | 유형     | 필수 | 설명                                  |
| ------- | ------ | -- | ----------------------------------- |
| `id`    | string | 예  | 사용자의 고유 ID                          |
| `op`    | string | 예  | `replace`                           |
| `path`  | string | 예  | `teamRoles`                         |
| `value` | array  | 예  | `teamName` 및 `roleName`을 포함하는 객체 배열 |

<div id="examples">
  #### 예시
</div>

<Tabs>
  <Tab title="팀 역할 할당 요청">
    ```bash theme={null}
    PATCH /scim/Users/abc
    ```

    ```json theme={null}
    {
      "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
      "Operations": [
        {
          "op": "replace",
          "path": "teamRoles",
          "value": [
            {
              "roleName": "admin",
              "teamName": "team1"
            }
          ]
        }
      ]
    }
    ```
  </Tab>

  <Tab title="팀 역할 할당 응답">
    ```text theme={null}
    (상태 200)
    ```

    ```json theme={null}
    {
      "active": true,
      "displayName": "Dev User 1",
      "emails": [
        {
          "primary": true,
          "value": "dev-user1@example.com"
        }
      ],
      "id": "abc",
      "meta": {
        "resourceType": "User",
        "created": "2023-10-01T00:00:00Z",
        "lastModified": "2023-10-01T00:00:00Z",
        "location": "Users/abc"
      },
      "schemas": [
        "urn:ietf:params:scim:schemas:core:2.0:User"
      ],
      "userName": "dev-user1",
      "teamRoles": [
        {
          "teamName": "team1",
          "roleName": "admin"
        }
      ],
      "organizationRole": "admin"
    }
    ```
  </Tab>
</Tabs>

<div id="add-to-registry">
  ### 레지스트리에 추가
</div>

지정된 레지스트리 수준 역할로 사용자를 레지스트리에 추가합니다.

<Note>이 오퍼레이션은 서비스 계정이 아닌 사용자에게만 적용됩니다. 서비스 계정에는 커스텀 역할이 지원되지 않습니다.</Note>

#### 엔드포인트

* **URL**: `[HOST-URL]/scim/Users/{id}`
* **방법**: `PATCH`

<div id="parameters">
  #### 매개변수
</div>

| 매개변수    | 유형     | 필수  | 설명                                      |
| ------- | ------ | --- | --------------------------------------- |
| `id`    | string | Yes | 사용자의 고유 ID                              |
| `op`    | string | Yes | `add`                                   |
| `path`  | string | Yes | `registryRoles`                         |
| `value` | array  | Yes | `registryName` 및 `roleName`을 포함하는 객체 배열 |

<div id="examples">
  #### 예시
</div>

<Tabs>
  <Tab title="레지스트리에 추가 요청">
    ```bash theme={null}
    PATCH /scim/Users/abc
    ```

    ```json theme={null}
    {
        "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
        "Operations": [
            {
                "op": "replace",
                "path": "registryRoles",
                "value": [
                    {
                        "roleName": "admin",
                        "registryName": "hello-registry"
                    }
                ]
            }
        ]
    }
    ```
  </Tab>

  <Tab title="레지스트리에 추가 응답">
    ```text theme={null}
    (Status 200)
    ```

    ```json theme={null}
    {
        "active": true,
        "displayName": "Dev User 1",
        "emails": [
            {
                "primary": true,
                "value": "dev-user1@example.com"
            }
        ],
        "id": "abc",
        "meta": {
            "resourceType": "User",
            "created": "2023-10-01T00:00:00Z",
            "lastModified": "2023-10-01T00:00:00Z",
            "location": "Users/abc"
        },
        "schemas": [
            "urn:ietf:params:scim:schemas:core:2.0:User"
        ],
        "userName": "dev-user1",
        "registryRoles": [
            {
                "registryName": "hello-registry",
                "roleName": "admin"
            }
        ],
        "organizationRole": "admin"
    }
    ```
  </Tab>
</Tabs>

<div id="remove-from-registry">
  ### 레지스트리에서 제거
</div>

레지스트리에서 사용자를 제거합니다.

<Note>
  * 제거 오퍼레이션은 RFC 7644 SCIM 프로토콜 사양을 따릅니다. 특정 레지스트리에서 사용자를 제거하려면 필터 구문 `"registryRoles[registryName eq \"{registry_name}\"]"`을 사용하고, 모든 레지스트리에서 사용자를 제거하려면 `"registryRoles"`를 사용하세요.
  * 이 오퍼레이션은 서비스 계정이 아닌 사용자에게만 적용됩니다. 레지스트리에서 서비스 계정을 제거하려면 W\&B 팀의 Settings에서 제거하세요.
</Note>

#### 엔드포인트

* **URL**: `[HOST-URL]/scim/Users/{id}`
* **방법**: `PATCH`

<div id="parameters">
  #### 매개변수
</div>

| 매개변수   | 유형     | 필수 | 설명                                                                          |
| ------ | ------ | -- | --------------------------------------------------------------------------- |
| `id`   | string | 예  | 사용자의 고유 ID                                                                  |
| `op`   | string | 예  | `remove`                                                                    |
| `path` | string | 예  | `"registryRoles[registryName eq \"{registry_name}\"]"` 또는 `"registryRoles"` |

<div id="examples">
  #### 예시
</div>

<Tabs>
  <Tab title="레지스트리에서 제거 요청">
    ```bash theme={null}
    PATCH /scim/Users/abc
    ```

    ```json theme={null}
    {
        "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
        "Operations": [
            {
                "op": "replace",
                "path": "registryRoles[registryName eq \"goodbye-registry\"]"
            }
        ]
    }
    ```
  </Tab>

  <Tab title="레지스트리에서 제거 응답">
    ```text theme={null}
    (상태 200)
    ```

    ```json theme={null}
    {
        "active": true,
        "displayName": "Dev User 1",
        "emails": [
            {
                "primary": true,
                "value": "dev-user1@example.com"
            }
        ],
        "id": "abc",
        "meta": {
            "resourceType": "User",
            "created": "2023-10-01T00:00:00Z",
            "lastModified": "2023-10-01T00:00:00Z",
            "location": "Users/abc"
        },
        "schemas": [
            "urn:ietf:params:scim:schemas:core:2.0:User"
        ],
        "userName": "dev-user1",
        "registryRoles": [
            {
                "registryName": "hello-registry",
                "roleName": "admin"
            }
        ],
        "organizationRole": "admin"
    }
    ```
  </Tab>
</Tabs>

<Tabs>
  <Tab title="모든 레지스트리에서 제거 요청">
    ```bash theme={null}
    PATCH /scim/Users/abc
    ```

    ```json theme={null}
    {
        "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
        "Operations": [
            {
                "op": "replace",
                "path": "registryRoles"
            }
        ]
    }
    ```
  </Tab>

  <Tab title="모든 레지스트리에서 제거 응답">
    ```text theme={null}
    (상태 200)
    ```

    ```json theme={null}
    {
        "active": true,
        "displayName": "Dev User 1",
        "emails": [
            {
                "primary": true,
                "value": "dev-user1@example.com"
            }
        ],
        "id": "abc",
        "meta": {
            "resourceType": "User",
            "created": "2023-10-01T00:00:00Z",
            "lastModified": "2023-10-01T00:00:00Z",
            "location": "Users/abc"
        },
        "schemas": [
            "urn:ietf:params:scim:schemas:core:2.0:User"
        ],
        "userName": "dev-user1",
        "organizationRole": "admin"
    }
    ```
  </Tab>
</Tabs>

<div id="group-resource">
  ## 그룹 리소스
</div>

SCIM group 리소스는 W\&B 팀에 매핑됩니다. 이 섹션의 엔드포인트를 사용하면 팀을 생성하고, 팀 구성원을 관리하고, ID 공급자 또는 자동화를 통해 팀 수준 저장소를 (선택적으로) 설정할 수 있습니다. IAM에서 SCIM group을 생성하면 W\&B 팀이 생성되어 이에 매핑되며, 다른 SCIM group 오퍼레이션도 해당 팀을 대상으로 수행됩니다. 팀 생성 시 맞춤형 저장소를 설정하려면 요청에 `storageBucket`을 포함하세요.

<div id="service-accounts">
  ### 서비스 계정
</div>

SCIM을 사용해 W\&B 팀을 생성하면 서비스 계정의 Team 리소스에 대한 액세스를 유지할 수 있도록 모든 조직 수준 서비스 계정이 자동으로 Team에 추가됩니다.

<div id="filter-groups">
  ### 그룹 필터링
</div>

`/Groups` 엔드포인트는 특정 Teams를 검색하기 위한 필터링을 지원합니다.

<div id="supported-filters">
  #### 지원되는 필터
</div>

`/Groups` 엔드포인트는 다음 필터를 지원합니다:

* `displayName eq "value"`: 팀 표시 이름을 기준으로 필터링합니다.

<div id="examples">
  #### 예시
</div>

```bash theme={null}
GET /scim/Groups?filter=displayName eq "engineering-team"
```

<div id="get-team">
  ### 팀 조회
</div>

팀의 고유 ID를 제공해 팀 정보를 조회합니다.

#### 엔드포인트

* **URL**: `[HOST-URL]/scim/Groups/{id}`
* **방법**: `GET`

<div id="examples">
  #### 예시
</div>

<Tabs>
  <Tab title="요청">
    ```bash theme={null}
    GET /scim/Groups/ghi
    ```
  </Tab>

  <Tab title="응답">
    ```text theme={null}
    (상태 200)
    ```

    ```json theme={null}
    {
      "displayName": "acme-devs",
      "id": "ghi",
      "members": [
        {
          "Value": "abc",
          "Ref": "",
          "Type": "",
          "Display": "dev-user1"
        }
      ],
      "meta": {
        "resourceType": "Group",
        "created": "2023-10-01T00:00:00Z",
        "lastModified": "2023-10-01T00:00:00Z",
        "location": "Groups/ghi"
      },
      "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"]
    }
    ```
  </Tab>
</Tabs>

<div id="list-teams">
  ### Teams 목록
</div>

Teams 목록을 조회합니다.

#### 엔드포인트

* **URL**: `[HOST-URL]/scim/Groups`
* **방법**: `GET`

<div id="examples">
  #### 예시
</div>

<Tabs>
  <Tab title="요청">
    ```bash theme={null}
    GET /scim/Groups
    ```
  </Tab>

  <Tab title="응답">
    ```text theme={null}
    (상태 200)
    ```

    ```json theme={null}
    {
        "Resources": [
            {
                "displayName": "acme-devs",
                "id": "ghi",
                "members": [
                    {
                        "Value": "abc",
                        "Ref": "",
                        "Type": "",
                        "Display": "dev-user1"
                    }
                ],
                "meta": {
                    "resourceType": "Group",
                    "created": "2023-10-01T00:00:00Z",
                    "lastModified": "2023-10-01T00:00:00Z",
                    "location": "Groups/ghi"
                },
                "schemas": [
                    "urn:ietf:params:scim:schemas:core:2.0:Group"
                ]
            }
        ],
        "itemsPerPage": 9999,
        "schemas": [
            "urn:ietf:params:scim:api:messages:2.0:ListResponse"
        ],
        "startIndex": 1,
        "totalResults": 1
    }
    ```
  </Tab>
</Tabs>

<div id="create-team">
  ### 팀 생성
</div>

새 팀 리소스를 생성합니다.

#### 엔드포인트

* **URL**: `[HOST-URL]/scim/Groups`
* **방법**: `POST`

<div id="supported-fields">
  #### 지원 필드
</div>

| 필드              | 유형      | 필수                                  |
| --------------- | ------- | ----------------------------------- |
| `displayName`   | String  | 예                                   |
| `members`       | 다중 값 배열 | 예 (`value` 하위 필드는 필수이며 사용자 ID에 매핑됨) |
| `storageBucket` | 객체      | 아니요                                 |

팀을 생성할 때 `storageBucket` 객체를 포함하면 팀 수준의 [Bring your own bucket (BYOB)](/ko/platform/hosting/data-security/secure-storage-connector)을 구성할 수 있습니다. 이를 생략하면 팀은 기본 저장소 또는 인스턴스 수준 저장소를 사용합니다. BYOB 가이드를 참고해 bucket을 프로비저닝하고(정책, CORS, 자격 증명) 공급자별 저장소 주소 형식을 확인하세요. `storageBucket` 객체에는 다음 하위 필드가 있습니다:

* **필수**: `name` (bucket 이름), `provider` (`COREWEAVE`, `AWS`, `AZURE`, `GCP`, `MINIO` 중 하나). 값은 대소문자를 구분하므로 표시된 대로 대문자를 사용하세요.
* **선택**: `path` (bucket 내 경로 접두사), `kmsKeyId` (암호화용 KMS 키, 예: AWS), `awsExternalId` (AWS 교차 계정 액세스), `azureTenantId` (Azure 테넌트 ID), `azureClientId` (Azure 관리 ID 클라이언트 ID).

W\&B는 팀을 생성하기 전에 bucket이 존재하고 접근 가능한지 검증합니다. 검증에 실패하면 SCIM 요청이 실패하고 팀은 생성되지 않습니다.

유효하지 않은 `provider` 값이 지정되면 허용되는 값을 나열한 SCIM 오류와 함께 `400 Bad Request`를 반환합니다.

<div id="examples">
  #### 예시
</div>

이 예시에서는 맞춤형 저장소 없이 팀을 생성하는 방법과 특정 공급자에서 BYOB 저장소를 사용해 팀을 생성하는 방법을 보여줍니다. 예시 요청을 보려면 원하는 저장소 설정 탭을 선택하고, 예시 응답을 보려면 **응답** 탭을 선택하세요.

<Tabs>
  <Tab title="요청 (BYOB 없음)">
    ```bash theme={null}
    POST /scim/Groups
    ```

    ```json theme={null}
    {
        "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
        "displayName": "wandb-support",
        "members": [
            {
                "value": "def"
            }
        ]
    }
    ```
  </Tab>

  <Tab title="CoreWeave">
    ```bash theme={null}
    POST /scim/Groups
    Content-Type: application/scim+json
    ```

    ```json theme={null}
    {
      "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
      "displayName": "ml-training-team",
      "members": [
        {
          "value": "user@example.com",
          "display": "user@example.com"
        }
      ],
      "storageBucket": {
        "name": "wandb-coreweave-bucket",
        "provider": "COREWEAVE",
        "path": "ml-training/experiments"
      }
    }
    ```
  </Tab>

  <Tab title="AWS S3">
    ```bash theme={null}
    POST /scim/Groups
    Content-Type: application/scim+json
    ```

    ```json theme={null}
    {
      "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
      "displayName": "ml-team",
      "members": [
        {
          "value": "user@example.com",
          "display": "user@example.com"
        }
      ],
      "storageBucket": {
        "name": "my-company-wandb-data",
        "provider": "AWS",
        "path": "ml-team/experiments",
        "kmsKeyId": "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012",
        "awsExternalId": "wandb-external-id-abc123"
      }
    }
    ```
  </Tab>

  <Tab title="Azure">
    ```bash theme={null}
    POST /scim/Groups
    Content-Type: application/scim+json
    ```

    ```json theme={null}
    {
      "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
      "displayName": "research-team",
      "members": [],
      "storageBucket": {
        "name": "wandbstorage",
        "provider": "AZURE",
        "path": "research/artifacts",
        "azureTenantId": "12345678-1234-1234-1234-123456789012",
        "azureClientId": "87654321-4321-4321-4321-210987654321"
      }
    }
    ```
  </Tab>

  <Tab title="GCP">
    ```bash theme={null}
    POST /scim/Groups
    Content-Type: application/scim+json
    ```

    ```json theme={null}
    {
      "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
      "displayName": "data-science-team",
      "members": [
        {
          "value": "VXNlcjox",
          "display": "jane.doe@example.com"
        },
        {
          "value": "VXNlcjoy",
          "display": "john.smith@example.com"
        }
      ],
      "storageBucket": {
        "name": "my-gcs-bucket",
        "provider": "GCP",
        "path": "data-science/runs"
      }
    }
    ```
  </Tab>

  <Tab title="응답">
    ```text theme={null}
    (Status 201)
    ```

    ```json theme={null}
    {
        "displayName": "wandb-support",
        "id": "jkl",
        "members": [
            {
                "Value": "def",
                "Ref": "",
                "Type": "",
                "Display": "dev-user2"
            }
        ],
        "meta": {
            "resourceType": "Group",
            "created": "2023-10-01T00:00:00Z",
            "lastModified": "2023-10-01T00:00:00Z",
            "location": "Groups/jkl"
        },
        "schemas": [
            "urn:ietf:params:scim:schemas:core:2.0:Group"
        ]
    }
    ```
  </Tab>
</Tabs>

<div id="update-team">
  ### 팀 업데이트
</div>

기존 팀의 멤버십 목록을 업데이트합니다.

#### 엔드포인트

* **URL**: `[HOST-URL]/scim/Groups/{id}`
* **방법**: `PATCH`
* **지원되는 오퍼레이션**: `add` 멤버 추가, `remove` 멤버 제거, `replace` 멤버 교체.

<Note>
  - `remove` 오퍼레이션은 RFC 7644 SCIM 프로토콜 사양을 따릅니다. 특정 사용자를 제거하려면 필터 구문 `members[value eq "{user_id}"]`을 사용하고, 팀에서 모든 사용자를 제거하려면 `members`를 사용하세요.

    **사용자 식별**: 멤버 오퍼레이션에서 `{user_id}`는 다음 중 하나일 수 있습니다.

    * W\&B 사용자 ID.
    * 이메일 주소(예: "[user@example.com](mailto:user@example.com)").
  - 이러한 오퍼레이션은 서비스 계정이 아니라 사용자에 대해서만 작동합니다. 팀의 서비스 계정은 W\&B 팀의 Settings에서 업데이트하세요.
</Note>

<Info>
  요청에서 `{team_id}`를 실제 팀 ID로, `{user_id}`를 실제 사용자 ID 또는 이메일 주소로 바꾸세요.
</Info>

<div id="replace-team-members">
  ### 팀 구성원 교체
</div>

팀의 모든 구성원을 새 목록으로 교체합니다.

<Note>이 오퍼레이션은 서비스 계정이 아닌 사용자에 대해서만 작동합니다. 서비스 계정은 W\&B 팀의 Settings에서 관리하세요.</Note>

#### 엔드포인트

* **URL**: `[HOST-URL]/scim/Groups/{id}`
* **방법**: `PUT`

<Tabs>
  <Tab title="요청">
    ```bash theme={null}
    PUT /scim/Groups/{team_id}
    ```

    ```json theme={null}
    {
        "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
        "displayName": "acme-devs",
        "members": [
            {
                "value": "{user_id_1}"
            },
            {
                "value": "{user_id_2}"
            }
        ]
    }
    ```
  </Tab>

  <Tab title="응답">
    ```text theme={null}
    (Status 200)
    ```

    ```json theme={null}
    {
        "displayName": "acme-devs",
        "id": "ghi",
        "members": [
            {
                "Value": "user_id_1",
                "Ref": "",
                "Type": "",
                "Display": "user1"
            },
            {
                "Value": "user_id_2",
                "Ref": "",
                "Type": "",
                "Display": "user2"
            }
        ],
        "meta": {
            "resourceType": "Group",
            "created": "2023-10-01T00:00:00Z",
            "lastModified": "2023-10-01T00:01:00Z",
            "location": "Groups/ghi"
        },
        "schemas": [
            "urn:ietf:params:scim:schemas:core:2.0:Group"
        ]
    }
    ```
  </Tab>
</Tabs>

<div id="add-a-user-to-a-team">
  ### 팀에 사용자 추가
</div>

`acme-devs`에 `dev-user2` 추가:

<Note>이 오퍼레이션은 서비스 계정이 아닌 사용자에 대해서만 작동합니다. 서비스 계정은 W\&B Team의 Settings에서 관리하세요.</Note>

<Tabs>
  <Tab title="요청">
    ```bash theme={null}
    PATCH /scim/Groups/{team_id}
    ```

    ```json theme={null}
    {
        "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
        "Operations": [
            {
                "op": "add",
                "path": "members",
                "value": [
                    {
                        "value": "{user_id}"
                    }
                ]
            }
        ]
    }
    ```
  </Tab>

  <Tab title="응답">
    ```text theme={null}
    (Status 200)
    ```

    ```json theme={null}
    {
        "displayName": "acme-devs",
        "id": "ghi",
        "members": [
            {
                "Value": "abc",
                "Ref": "",
                "Type": "",
                "Display": "dev-user1"
            },
            {
                "Value": "def",
                "Ref": "",
                "Type": "",
                "Display": "dev-user2"
            }
        ],
        "meta": {
            "resourceType": "Group",
            "created": "2023-10-01T00:00:00Z",
            "lastModified": "2023-10-01T00:01:00Z",
            "location": "Groups/ghi"
        },
        "schemas": [
            "urn:ietf:params:scim:schemas:core:2.0:Group"
        ]
    }
    ```
  </Tab>
</Tabs>

<div id="remove-a-specific-user-from-a-team">
  ### 팀에서 특정 사용자 제거
</div>

`acme-devs`에서 `dev-user2`를 제거하는 예:

<Note>이 오퍼레이션은 사용자에만 적용되며 서비스 계정에는 적용되지 않습니다. 서비스 계정은 W\&B Team의 Settings에서 관리하세요.</Note>

<Tabs>
  <Tab title="요청">
    ```bash theme={null}
    PATCH /scim/Groups/{team_id}
    ```

    ```json theme={null}
    {
        "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
        "Operations": [
            {
                "op": "remove",
                "path": "members[value eq \"{user_id}\"]"
            }
        ]
    }
    ```
  </Tab>

  <Tab title="응답">
    ```text theme={null}
    (상태 200)
    ```

    ```json theme={null}
    {
        "displayName": "acme-devs",
        "id": "ghi",
        "members": [
            {
                "Value": "abc",
                "Display": "dev-user1"
            }
        ],
        "meta": {
            "resourceType": "Group",
            "created": "2023-10-01T00:00:00Z",
            "lastModified": "2023-10-01T00:01:00Z",
            "location": "Groups/ghi"
        },
        "schemas": [
            "urn:ietf:params:scim:schemas:core:2.0:Group"
        ]
    }
    ```
  </Tab>
</Tabs>

<div id="remove-all-users-from-a-team">
  ### 팀에서 모든 사용자 제거
</div>

`acme-devs`에서 모든 사용자를 제거하는 예:

<Note>이 오퍼레이션은 사용자에만 적용되며 서비스 계정에는 적용되지 않습니다. 서비스 계정은 W\&B Team의 Settings에서 관리하세요.</Note>

<Tabs>
  <Tab title="요청">
    ```bash theme={null}
    PATCH /scim/Groups/{team_id}
    ```

    ```json theme={null}
    {
        "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
        "Operations": [
            {
                "op": "remove",
                "path": "members"
            }
        ]
    }
    ```
  </Tab>

  <Tab title="응답">
    ```text theme={null}
    (상태 200)
    ```

    ```json theme={null}
    {
        "displayName": "acme-devs",
        "id": "ghi",
        "members": null,
        "meta": {
            "resourceType": "Group",
            "created": "2023-10-01T00:00:00Z",
            "lastModified": "2023-10-01T00:01:00Z",
            "location": "Groups/ghi"
        },
        "schemas": [
            "urn:ietf:params:scim:schemas:core:2.0:Group"
        ]
    }
    ```
  </Tab>
</Tabs>

<div id="delete-team">
  ### 팀 삭제
</div>

팀에는 추가 데이터가 연결되어 있으므로 SCIM API에서는 팀 삭제를 지원하지 않습니다. 모든 항목을 삭제할지 확인하려면 W\&B App에서 팀을 삭제하세요.

<div id="role-resource">
  ## 역할 리소스
</div>

SCIM 역할 리소스는 W\&B 커스텀 역할에 매핑됩니다. 이 섹션의 엔드포인트를 사용하여 커스텀 역할을 프로그래밍 방식으로 생성하고 유지 관리하세요(예: 역할 정의를 액세스 정책과 동기화된 상태로 유지). 앞서 언급했듯이 `/Roles` 엔드포인트는 공식 SCIM 스키마의 일부가 아니며, W\&B는 W\&B 조직에서 커스텀 역할을 자동으로 관리할 수 있도록 `/Roles` 엔드포인트를 추가합니다.

<div id="get-custom-role">
  ### 커스텀 역할 조회
</div>

역할의 고유 ID를 지정하여 커스텀 역할 정보를 조회합니다.

#### 엔드포인트

* **URL**: `[HOST-URL]/scim/Roles/{id}`
* **방법**: `GET`

<div id="examples">
  #### 예시
</div>

<Tabs>
  <Tab title="요청">
    ```bash theme={null}
    GET /scim/Roles/abc
    ```
  </Tab>

  <Tab title="응답">
    ```text theme={null}
    (Status 200)
    ```

    ```json theme={null}
    {
        "description": "A sample custom role for example",
        "id": "Um9sZTo3",
        "inheritedFrom": "member", // 사전 정의된 역할임을 나타냅니다
        "meta": {
            "resourceType": "Role",
            "created": "2023-11-20T23:10:14Z",
            "lastModified": "2023-11-20T23:31:23Z",
            "location": "Roles/Um9sZTo3"
        },
        "name": "Sample custom role",
        "organizationID": "T3JnYW5pemF0aW9uOjE0ODQ1OA==",
        "permissions": [
            {
                "name": "artifact:read",
                "isInherited": true // 사전 정의된 member 역할에서 상속됨
            },
            ...
            ...
            {
                "name": "project:update",
                "isInherited": false // 관리자가 추가한 커스텀 권한
            }
        ],
        "schemas": [
            ""
        ]
    }
    ```
  </Tab>
</Tabs>

<div id="list-custom-roles">
  ### 커스텀 역할 목록 조회
</div>

W\&B 조직의 모든 커스텀 역할 정보를 조회합니다.

#### 엔드포인트

* **URL**: `[HOST-URL]/scim/Roles`
* **방법**: `GET`

<div id="examples">
  #### 예시
</div>

<Tabs>
  <Tab title="요청">
    ```bash theme={null}
    GET /scim/Roles
    ```
  </Tab>

  <Tab title="응답">
    ```text theme={null}
    (Status 200)
    ```

    ```json theme={null}
    {
       "Resources": [
            {
                "description": "A sample custom role for example",
                "id": "Um9sZTo3",
                "inheritedFrom": "member", // 커스텀 역할이 상속하는 사전 정의된 역할을 나타냅니다
                "meta": {
                    "resourceType": "Role",
                    "created": "2023-11-20T23:10:14Z",
                    "lastModified": "2023-11-20T23:31:23Z",
                    "location": "Roles/Um9sZTo3"
                },
                "name": "Sample custom role",
                "organizationID": "T3JnYW5pemF0aW9uOjE0ODQ1OA==",
                "permissions": [
                    {
                        "name": "artifact:read",
                        "isInherited": true // member 사전 정의된 역할에서 상속됨
                    },
                    ...
                    ...
                    {
                        "name": "project:update",
                        "isInherited": false // 관리자가 추가한 커스텀 권한
                    }
                ],
                "schemas": [
                    ""
                ]
            },
            {
                "description": "Another sample custom role for example",
                "id": "Um9sZToxMg==",
                "inheritedFrom": "viewer", // 커스텀 역할이 상속하는 사전 정의된 역할을 나타냅니다
                "meta": {
                    "resourceType": "Role",
                    "created": "2023-11-21T01:07:50Z",
                    "location": "Roles/Um9sZToxMg=="
                },
                "name": "Sample custom role 2",
                "organizationID": "T3JnYW5pemF0aW9uOjE0ODQ1OA==",
                "permissions": [
                    {
                        "name": "launchagent:read",
                        "isInherited": true // viewer 사전 정의된 역할에서 상속됨
                    },
                    ...
                    ...
                    {
                        "name": "run:stop",
                        "isInherited": false // 관리자가 추가한 커스텀 권한
                    }
                ],
                "schemas": [
                    ""
                ]
            }
        ],
        "itemsPerPage": 9999,
        "schemas": [
            "urn:ietf:params:scim:api:messages:2.0:ListResponse"
        ],
        "startIndex": 1,
        "totalResults": 2
    }
    ```
  </Tab>
</Tabs>

<div id="create-custom-role">
  ### 커스텀 역할 생성
</div>

W\&B 조직에 새 커스텀 역할을 만듭니다.

#### 엔드포인트

* **URL**: `[HOST-URL]/scim/Roles`
* **방법**: `POST`

<div id="supported-fields">
  #### 지원 필드
</div>

| 필드              | 유형           | 필수                                                                                                                                        |
| --------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `name`          | String       | 커스텀 역할의 이름                                                                                                                                |
| `description`   | String       | 커스텀 역할에 대한 설명                                                                                                                             |
| `permissions`   | Object array | 권한 객체 배열입니다. 각 객체에는 값이 `w&bobject:operation` 형식인 `name` 문자열 필드가 포함됩니다. 예를 들어, W\&B run의 delete 오퍼레이션에 대한 권한 객체라면 `name`은 `run:delete`입니다. |
| `inheritedFrom` | String       | 커스텀 역할이 상속할 사전 정의된 역할입니다. `member` 또는 `viewer` 중 하나일 수 있습니다.                                                                              |

<div id="examples">
  #### 예시
</div>

<Tabs>
  <Tab title="요청">
    ```bash theme={null}
    POST /scim/Roles
    ```

    ```json theme={null}
    {
        "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Role"],
        "name": "Sample custom role",
        "description": "A sample custom role for example",
        "permissions": [
            {
                "name": "project:update"
            }
        ],
        "inheritedFrom": "member"
    }
    ```
  </Tab>

  <Tab title="응답">
    ```text theme={null}
    (Status 201)
    ```

    ```json theme={null}
    {
        "description": "A sample custom role for example",
        "id": "Um9sZTo3",
        "inheritedFrom": "member", // 사전 정의된 역할을 나타냅니다
        "meta": {
            "resourceType": "Role",
            "created": "2023-11-20T23:10:14Z",
            "lastModified": "2023-11-20T23:31:23Z",
            "location": "Roles/Um9sZTo3"
        },
        "name": "Sample custom role",
        "organizationID": "T3JnYW5pemF0aW9uOjE0ODQ1OA==",
        "permissions": [
            {
                "name": "artifact:read",
                "isInherited": true // member 사전 정의된 역할에서 상속됨
            },
            ...
            ...
            {
                "name": "project:update",
                "isInherited": false // 관리자가 추가한 커스텀 권한
            }
        ],
        "schemas": [
            ""
        ]
    }
    ```
  </Tab>
</Tabs>

<div id="update-custom-role">
  ### 커스텀 역할 업데이트
</div>

다음 섹션에서는 기존 커스텀 역할에 권한을 추가하거나 제거하는 방법을 설명합니다.

<div id="add-permissions-to-role">
  #### 역할에 권한 추가
</div>

기존 커스텀 역할에 권한을 추가합니다.

##### 엔드포인트

* **URL**: `[HOST-URL]/scim/Roles/{id}`
* **방법**: `PATCH`

<Tabs>
  <Tab title="요청">
    ```bash theme={null}
    PATCH /scim/Roles/{role_id}
    ```

    ```json theme={null}
    {
        "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
        "Operations": [
            {
                "op": "add",
                "path": "permissions",
                "value": [
                    {
                        "name": "project:delete"
                    },
                    {
                        "name": "run:stop"
                    }
                ]
            }
        ]
    }
    ```
  </Tab>

  <Tab title="응답">
    ```text theme={null}
    (Status 200)
    ```

    새 권한이 추가된 역할을 반환합니다.
  </Tab>
</Tabs>

<div id="remove-a-permission-from-a-role">
  #### 역할에서 권한 제거
</div>

기존 커스텀 역할에서 권한을 제거합니다.

<div id="endpoint">
  ##### Endpoint
</div>

* **URL**: `[HOST-URL]/scim/Roles/{id}`
* **방법**: `PATCH`

<Tabs>
  <Tab title="요청">
    ```bash theme={null}
    PATCH /scim/Roles/{role_id}
    ```

    ```json theme={null}
    {
        "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
        "Operations": [
            {
                "op": "remove",
                "path": "permissions",
                "value": [
                    {
                        "name": "project:update"
                    }
                ]
            }
        ]
    }
    ```
  </Tab>

  <Tab title="응답">
    ```text theme={null}
    (Status 200)
    ```

    지정한 권한이 제거된 업데이트된 역할을 반환합니다.
  </Tab>
</Tabs>

<div id="replace-custom-role">
  ### 커스텀 역할 교체
</div>

커스텀 역할 정의 전체를 교체합니다.

#### 엔드포인트

* **URL**: `[HOST-URL]/scim/Roles/{id}`
* **방법**: `PUT`

<Tabs>
  <Tab title="요청">
    ```bash theme={null}
    PUT /scim/Roles/{role_id}
    ```

    ```json theme={null}
    {
        "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Role"],
        "name": "Updated custom role",
        "description": "Updated description for the custom role",
        "permissions": [
            {
                "name": "project:read"
            },
            {
                "name": "run:read"
            },
            {
                "name": "artifact:read"
            }
        ],
        "inheritedFrom": "viewer"
    }
    ```
  </Tab>

  <Tab title="응답">
    ```text theme={null}
    (Status 200)
    ```

    교체된 역할 정의를 반환합니다.
  </Tab>
</Tabs>

<div id="delete-custom-role">
  ### 커스텀 역할 삭제
</div>

W\&B 조직에서 커스텀 역할을 삭제합니다. **이 오퍼레이션은 신중하게 사용하세요**. 삭제 전에 해당 커스텀 역할이 할당되어 있던 모든 사용자에게는, 커스텀 역할이 상속했던 사전 정의된 역할이 대신 할당됩니다.

#### 엔드포인트

* **URL**: `[HOST-URL]/scim/Roles/{id}`
* **방법**: `DELETE`

<div id="examples">
  #### 예시
</div>

<Tabs>
  <Tab title="요청">
    ```bash theme={null}
    DELETE /scim/Roles/abc
    ```
  </Tab>

  <Tab title="응답">
    ```text theme={null}
    (Status 204 No Content)
    ```
  </Tab>
</Tabs>

<div id="advanced-features">
  ## 고급 특성
</div>

다음 섹션에서는 SCIM 인테그레이션이 프로덕션 환경에서 안전하게 작동하도록 지원하는 선택적 기능(ETag 기반 동시성 제어 및 표준 오류 응답)에 대해 설명합니다.

<div id="etag-support">
  ### ETag 지원
</div>

SCIM API는 동시 수정 충돌을 방지하기 위해 조건부 업데이트용 ETag를 지원합니다. 이는 여러 관리자 또는 자동화 시스템이 동일한 리소스를 업데이트할 때 중요하며, 한 업데이트가 다른 업데이트를 모르게 덮어쓰는 일을 방지해 줍니다. ETag는 `ETag` 응답 헤더와 `meta.version` 필드로 반환됩니다.

<div id="etags">
  #### ETags
</div>

ETags를 사용하려면 다음 단계를 따르세요:

1. **현재 ETag 조회**: 리소스를 GET할 때 응답 헤더의 ETag를 확인합니다.
2. **조건부 업데이트**: 업데이트할 때 `If-Match` 헤더에 ETag를 포함합니다.

<div id="examples">
  #### 예시
</div>

```text theme={null}
# 사용자 조회 및 ETag 기록
GET /scim/Users/abc
# 응답에 포함: ETag: W/"xyz123"

# ETag로 업데이트
PATCH /scim/Users/abc
If-Match: W/"xyz123"

{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
    "Operations": [
        {
            "op": "replace",
            "path": "organizationRole",
            "value": "admin"
        }
    ]
}
```

`412 Precondition Failed` 오류 응답은 리소스를 조회한 후 해당 리소스가 수정되었음을 나타냅니다.

<div id="error-handling">
  ### 오류 처리
</div>

SCIM API는 표준 SCIM 오류 응답을 반환합니다.

| 상태 코드 | 설명                             |
| ----- | ------------------------------ |
| `200` | 성공                             |
| `201` | 생성됨                            |
| `204` | No Content (삭제 성공)             |
| `400` | 잘못된 요청: 매개변수 또는 요청 본문이 올바르지 않음 |
| `401` | 권한 없음: 인증 실패                   |
| `403` | 접근 금지: 권한 부족                   |
| `404` | 찾을 수 없음: 리소스가 존재하지 않음          |
| `409` | 충돌: 리소스가 이미 존재함                |
| `412` | 사전 조건 실패: ETag 불일치             |
| `500` | 내부 서버 오류                       |

<div id="implementation-differences-per-deployment-type">
  ### 배포 유형별 구현 차이
</div>

W\&B는 별도의 SCIM API 구현 두 가지를 유지 관리하며, 지원되는 특성은 다음과 같이 서로 다릅니다. SCIM과 통합하기 전에 아래 표를 검토하여, 의존하는 오퍼레이션이 사용 중인 배포 유형에서 사용 가능한지 확인하세요.

| 특성                        | Multi-tenant Cloud | Dedicated Cloud and Self-Managed |
| ------------------------- | ------------------ | -------------------------------- |
| 사용자 이메일 업데이트              | -                  | ✓                                |
| 사용자 표시 이름 업데이트            | -                  | ✓                                |
| 사용자 비활성화                  | ✓                  | ✓                                |
| 사용자 재활성화                  | -                  | ✓                                |
| 사용자당 여러 이메일               | ✓                  | -                                |
| 생성/업데이트 시 `modelsSeat` 설정 | ✓                  | ✓                                |
| 생성/업데이트 시 `weaveRole` 설정  | ✓                  | ✓                                |

<div id="limitations">
  ## 제한 사항
</div>

SCIM 인테그레이션을 설계할 때는 다음 제약 사항을 염두에 두세요:

* **최대 결과 수**: 요청당 항목 9,999개
* **Dedicated Cloud and Self-Managed**: 사용자당 이메일 주소는 1개만 지원합니다.
* **팀 삭제**: SCIM을 통해서는 지원되지 않습니다(W\&B 웹 인터페이스 사용).
* **사용자 재활성화**: Multi-tenant Cloud 환경에서는 지원되지 않습니다.
* **시트 한도**: 조직 시트 한도에 도달하면 오퍼레이션이 실패할 수 있습니다.
