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

# SCIM으로 사용자, 그룹 및 역할 관리

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

<Note>
  [SCIM의 실제 사용 방법을 보여주는 비디오](https://www.youtube.com/watch?v=Nw3QBqV0I-o)를 시청하세요(12분).
</Note>

<h2 id="overview">
  개요
</h2>

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

W\&B의 SCIM API는 Okta, Microsoft Entra 등의 ID 공급자와 호환됩니다. Okta, Microsoft Entra 및 기타 ID 공급자를 사용한 SSO 설정은 [SSO 문서](/ko/products/wandb/platform/hosting/iam/sso)를 참조하세요.

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

<h3 id="supported-features">
  지원되는 기능
</h3>

SCIM API는 다음 기능을 지원합니다.

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

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

  이 페이지의 예시에 사용된 `[HOST-URL]` 플레이스홀더의 값은 선택한 호스팅 옵션에 따라 달라집니다.

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

<h2 id="authentication">
  인증
</h2>

모든 SCIM 요청은 관리자 주체(principal)로 인증해야 합니다. 조직 관리자는 **Bearer 토큰** 또는 **HTTP Basic** 자격 증명으로 인증할 수 있습니다. 키를 사용하는 경우 두 방식 모두 \_동일한 API 키 문자열\_을 사용합니다. 다음 섹션에서 주요 차이를 확인한 후 사용자 ID와 조직 범위 서비스 계정 중 하나를 선택하세요.

<h3 id="key-differences">
  주요 차이
</h3>

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

* 사용 대상: 사용자는 대화형으로 일회성 관리 작업을 수행할 때 적합합니다. 서비스 계정은 자동화 및 인테그레이션(CI/CD, 프로비저닝 도구)에 적합합니다.
* 자격 증명: Basic 인증의 경우 사용자는 사용자 이름과 API 키를 보내고, 서비스 계정은 사용자 이름 없이 API 키만 보냅니다. Bearer 인증의 경우 사용자 이름 없이 헤더에 API 키만 보냅니다.
* Bearer와 Basic 비교: Bearer는 키를 그대로 넣은 `Authorization: Bearer [API-KEY]`를 사용합니다. Basic은 `Authorization: Basic <base64(...)>`를 사용합니다(사용자는 `username:API-KEY`를 인코딩하고, 서비스 계정은 사용자 이름을 비우고 앞에 콜론을 붙인 `:API-KEY`를 인코딩합니다).
* 범위 및 권한: 인스턴스 관리자 또는 조직 관리자 사용자의 API 키나 [조직 범위 서비스 계정](/ko/products/wandb/platform/hosting/iam/service-accounts#organization-scoped-service-accounts)의 API 키를 사용하세요. [팀 범위 서비스 계정](/ko/products/wandb/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을 설정해야 합니다.

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

API 키를 Bearer 토큰으로 전송하세요.

```bash theme={"system"}
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]`를 플레이스홀더로 사용합니다. 이 값을 Admin 사용자 또는 조직 범위 서비스 계정의 실제 키로 바꾸세요.

**사용자 목록 조회**

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

**사용자 생성**

```bash theme={"system"}
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)을 참조하세요.

<h3 id="users">
  Users
</h3>

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

예를 들어 `demo:p@55w0rd`로 인증하려면 다음과 같이 합니다.

```bash theme={"system"}
Authorization: Basic ZGVtbzpwQDU1dzByZA==
```

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

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

예를 들어, API 키 `sa-p@55w0rd`로 인증하려면 다음과 같이 합니다.

```bash theme={"system"}
Authorization: Basic OnNhLXBANTV3MHJk
```

<h2 id="microsoft-entra-id-configuration">
  Microsoft Entra ID 설정
</h2>

SCIM API를 통해 Microsoft Entra ID에서 W\&B로 사용자 및 그룹을 자동으로 프로비저닝하도록 설정하려면 이 섹션을 참조하세요.

Entra SSO 설정 방법은 [Entra로 SSO 설정하기](/ko/products/wandb/platform/hosting/iam/sso)를 참조하세요.

<h3 id="tenant-url">
  Tenant URL
</h3>

Entra 엔터프라이즈 애플리케이션의 프로비저닝 설정에서 **Tenant URL**을 W\&B SCIM 기본 URL 뒤에 Entra 기능 플래그 쿼리 매개변수 `aadOptscim062020`을 추가한 값으로 설정하세요.

```text theme={"system"}
[HOST-URL]/scim?aadOptscim062020
```

예를 들어 인스턴스가 `https://wandb.example.com`에 있다면 테넌트 URL을 `https://wandb.example.com/scim?aadOptscim062020`으로 설정하세요.

`aadOptscim062020` 매개변수는 W\&B SCIM API에서 Entra 전용 처리를 활성화합니다. 이 매개변수가 없으면 Entra가 사용자 비활성화 요청에 JSON 불리언 값(`false` 또는 `true`) 대신 문자열 불리언 값(`"False"` 또는 `"True"`)을 담아 보낼 수 있으며, 이 경우 비활성화가 실패할 수 있습니다.

**Secret Token**에는 조직 Admin 사용자 또는 조직 범위 서비스 계정의 API 키를 입력하세요. 자세한 내용은 [인증](#authentication)을 참조하세요.

<Note>
  테넌트 URL에 `aadOptscim062020`을 추가하면 Microsoft Entra 관리 센터의 **Provision on demand** UI에서는 사용자 비활성화가 작동하지 않을 수 있습니다. 해당 UI는 여전히 문자열 불리언 값을 보내기 때문입니다. 비활성화를 수동으로 테스트하려면 `PatchOp` `Operations` 형식으로 `active`를 `false`로 바꾸는 SCIM `PATCH` 요청을 보내세요([사용자 비활성화](#deactivate-user) 참조).
</Note>

<h3 id="team-names">
  팀 이름
</h3>

W\&B 팀에 매핑되는 Entra 그룹의 이름은 `ml-platform`이나 `data-science`처럼 소문자와 하이픈으로 지정하세요. W\&B에 동기화하는 그룹의 표시 이름에는 공백, 밑줄 및 기타 특수 문자를 사용하지 마세요.

<h3 id="user-attribute-mappings">
  사용자 속성 매핑
</h3>

SCIM 사용자 프로비저닝을 위해 Entra에서 다음과 같이 속성 매핑을 설정하세요.

| W\&B 맞춤형 앱 속성 | 소스 속성 (Entra) | Apply this mapping | Match objects using this attribute |
| - | - | - | - |
| `emails[type eq "work"].value` | `mail` | Always | Yes |
| `active` | `Not([IsSoftDeleted])` | Always | |
| `displayName` | `displayName` | Always | |
| `userName` | `displayName` | Only on object creation | |

<Note>
  **Multi-tenant Cloud**에서는 조직이 사용자 계정을 관리하지 않습니다. 따라서 Multi-tenant Cloud에서는 SCIM을 통한 `displayName` 업데이트를 지원하지 않습니다. 자세한 내용은 [사용자 표시 이름 업데이트](#update-user-display-name)를 참조하세요.
</Note>

<h3 id="group-attribute-mappings">
  그룹 속성 매핑
</h3>

SCIM 그룹(팀) 프로비저닝을 위해 Entra에서 다음 속성 매핑을 설정하세요.

| W\&B 맞춤형 앱 속성 | 소스 속성(Entra) | Apply this mapping | Match objects using this attribute |
| - | - | - | - |
| `displayName` | `displayName` | Only on object creation | Yes |
| `members` | `members` | Always | |

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

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

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

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

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

  코드에서 SCIM \_응답\_의 `emails`를 읽는 경우, `emails`를 배열로 처리하고 primary 항목(또는 첫 번째 요소)을 읽도록 하세요.

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

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

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

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

<h4 id="endpoint">
  엔드포인트
</h4>

* **URL**: `[HOST-URL]/scim/Users/{id}`
* **메서드**: `GET`

<h4 id="parameters">
  매개변수
</h4>

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

<h4 id="example">
  예시
</h4>

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

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

    ```json theme={"system"}
    {
        "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`을 반환합니다.

    "활동"의 정의는 배포 유형에 따라 다릅니다.

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

<h3 id="list-users">
  사용자 목록 조회
</h3>

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

<h4 id="filter-users">
  사용자 필터링
</h4>

`/Users` 엔드포인트에서는 사용자 이름 또는 이메일로 사용자를 필터링할 수 있습니다.

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

<h5 id="example-2">
  예시
</h5>

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

<h4 id="endpoint-2">
  엔드포인트
</h4>

* **URL**: `[HOST-URL]/scim/Users`
* **메서드**: `GET`

<h4 id="example-3">
  예시
</h4>

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

  <Tab title="사용자 목록 응답">
    ```text theme={"system"}
    (Status 200)
    ```

    ```json theme={"system"}
    {
        "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`을 반환합니다.

    "활동"의 기준은 배포 유형에 따라 다릅니다.

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

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

조직에 새 사용자를 생성합니다.

<h4 id="endpoint-3">
  엔드포인트
</h4>

* **URL**: `[HOST-URL]/scim/Users`
* **메서드**: `POST`

<h4 id="parameters-2">
  매개변수
</h4>

| 매개변수 | 유형 | 필수 | 설명 |
| - | - | - | - |
| `emails` | array | 예 | 이메일 객체의 배열입니다. 기본 이메일이 반드시 포함되어야 합니다. |
| `userName` | string | 예 | 새 사용자의 사용자 이름입니다. |
| `modelsSeat` | string | 아니요 | Models 시트 수준입니다. `full`, `viewer`, `none` 중 하나입니다. 기본값은 `full`입니다. |
| `weaveRole` | string | 아니요 | Weave 역할 수준입니다. `full`, `viewer`, `none` 중 하나입니다. 기본값은 `full`입니다. |
| `registryAccess` | string | 아니요 | 레지스트리 사용 권한입니다. `enabled` 또는 `none` 중 하나입니다. 생략하면 조회 시점에 `modelsSeat`와 `weaveRole`을 기준으로 실제 액세스 권한이 결정됩니다. **Multi-tenant Cloud**와 **Dedicated Cloud** 및 **Self-Managed** v0.83.0 이상에서 사용할 수 있습니다. |

<h4 id="example-4">
  예시
</h4>

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

    ```json theme={"system"}
    {
        "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={"system"}
    POST /scim/Users
    ```

    ```json theme={"system"}
    {
        "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>

<h4 id="response">
  응답
</h4>

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

    ```json theme={"system"}
    {
        "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={"system"}
    (Status 201)
    ```

    ```json theme={"system"}
    {
        "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>

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

조직에 팀 범위 또는 조직 범위의 서비스 계정을 생성합니다. 이 엔드포인트를 사용하면 실제 사용자와 연결할 필요가 없는 자동화, 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>

<h4 id="endpoint-4">
  엔드포인트
</h4>

* **URL**: `[HOST-URL]/scim/Users`
* **메서드**: `POST`

<h4 id="parameters-3">
  매개변수
</h4>

| 매개변수 | 유형 | 필수 | 설명 |
| - | - | - | - |
| `userName` | string | 예 | 서비스 계정의 고유 이름입니다. |
| `accountType` | string | 예 | [팀 범위 서비스 계정](/ko/products/wandb/platform/hosting/iam/service-accounts#team-scoped-service-accounts)은 `SERVICE`, [조직 범위 서비스 계정](/ko/products/wandb/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`에 지정한 팀도 함께 포함하세요. |

<h4 id="example-5">
  예시
</h4>

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

    ```json theme={"system"}
    {
        "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={"system"}
    POST /scim/Users
    ```

    ```json theme={"system"}
    {
        "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>

<h4 id="response-2">
  응답
</h4>

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

    ```json theme={"system"}
    {
        "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={"system"}
    (Status 201)
    ```

    ```json theme={"system"}
    {
        "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`이 없거나 잘못된 값으로 설정되어 있습니다.

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

서비스 계정과 해당 계정의 조직 구성원 자격을 영구적으로 삭제합니다. 서비스 계정이 더 이상 필요하지 않을 때(예: 자동화 파이프라인을 폐기한 경우) 이 엔드포인트를 사용하세요. 이 작업은 영구 삭제이므로 SCIM을 통해 계정을 다시 활성화할 수 없습니다.

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

<h4 id="endpoint-5">
  엔드포인트
</h4>

* **URL**: `[HOST-URL]/scim/Users/{id}`
* **메서드**: `DELETE`

<h4 id="parameters-4">
  매개변수
</h4>

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

<h4 id="example-6">
  예시
</h4>

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

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

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

<Warning>
  **Admin 액세스 유지**

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

  운영 절차 수립에 도움이 필요하거나 Admin 액세스를 복원하려면 [지원팀](mailto:forge-support@coreweave.com)에 문의하세요.
</Warning>

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

<h4 id="endpoint-6">
  엔드포인트
</h4>

* **URL**: `[HOST-URL]/scim/Users/{id}`
* **메서드**: `DELETE`

<h4 id="parameters-5">
  매개변수
</h4>

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

<h4 id="example-7">
  예시
</h4>

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

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

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

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

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

**Multi-tenant Cloud에서는 지원되지 않습니다**. Multi-tenant Cloud에서는 사용자 계정을 조직에서 관리하지 않기 때문입니다.

<h4 id="endpoint-7">
  엔드포인트
</h4>

* **URL**: `[HOST-URL]/scim/Users/{id}`
* **메서드**: `PATCH`

<h4 id="parameters-6">
  매개변수
</h4>

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

<h4 id="example-8">
  예시
</h4>

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

    ```json theme={"system"}
    {
        "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={"system"}
    (Status 200)
    ```

    ```json theme={"system"}
    {
        "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>

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

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

**Multi-tenant Cloud에서는 지원되지 않습니다**. Multi-tenant Cloud에서는 사용자 계정을 조직에서 관리하지 않기 때문입니다.

<h4 id="endpoint-8">
  엔드포인트
</h4>

* **URL**: `[HOST-URL]/scim/Users/{id}`
* **메서드**: `PATCH`

<h4 id="parameters-7">
  매개변수
</h4>

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

<h4 id="example-9">
  예시
</h4>

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

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

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

    ```json theme={"system"}
    {
        "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>

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

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

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

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

<h4 id="endpoint-9">
  엔드포인트
</h4>

* **URL**: `[HOST-URL]/scim/Users/{id}`
* **메서드**: `PATCH`

<h4 id="parameters-8">
  매개변수
</h4>

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

<h4 id="example-10">
  예시
</h4>

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

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

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

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

<h4 id="response-3">
  응답
</h4>

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

    ```json theme={"system"}
    {
        "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={"system"}
    (Status 200)
    ```

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

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

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

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

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

<h4 id="endpoint-10">
  엔드포인트
</h4>

* **URL**: `[HOST-URL]/scim/Users/{id}`
* **메서드**: `PATCH`

<h4 id="parameters-9">
  매개변수
</h4>

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

<h4 id="example-11">
  예시
</h4>

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

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

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

    ```json theme={"system"}
    {
        "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>

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

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

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

<h4 id="endpoint-11">
  엔드포인트
</h4>

* **URL**: `[HOST-URL]/scim/Users/{id}`
* **메서드**: `PATCH`

<h4 id="parameters-10">
  매개변수
</h4>

| 매개변수 | 유형 | 필수 | 설명 |
| - | - | - | - |
| `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>

<h4 id="example-12">
  예시
</h4>

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

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

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

    ```json theme={"system"}
    {
        "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>

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

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

<Note>
  **Multi-tenant Cloud**와 v0.83.0 이상의 **Dedicated Cloud** 및 **Self-Managed**에서는 레지스트리 액세스가 Models 시트와 분리되어 있습니다. 사용자의 `weaveRole`이 `none`이 아니면 `modelsSeat`를 `none`으로 설정해도 더 이상 레지스트리 액세스가 철회되지 않습니다. 이러한 배포에서 레지스트리 액세스를 철회하려면 [레지스트리 액세스 업데이트](#update-registry-access)를 사용하여 `registryAccess`를 `none`으로 설정하세요.

  v0.82.0 이하의 **Dedicated Cloud** 및 **Self-Managed**에서는 레지스트리 액세스가 여전히 `modelsSeat`에 연동되어 있습니다. 이러한 릴리스에서 레지스트리 액세스를 철회하려면 `modelsSeat`를 `none`으로 설정하세요.
</Note>

<h4 id="endpoint-12">
  엔드포인트
</h4>

* **URL**: `[HOST-URL]/scim/Users/{id}`
* **메서드**: `PATCH`

<h4 id="parameters-11">
  매개변수
</h4>

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

<h4 id="example-13">
  예시
</h4>

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

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

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

    ```json theme={"system"}
    {
        "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>

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

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

<h4 id="endpoint-13">
  엔드포인트
</h4>

* **URL**: `[HOST-URL]/scim/Users/{id}`
* **메서드**: `PATCH`

<h4 id="parameters-12">
  매개변수
</h4>

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

<h4 id="example-14">
  예시
</h4>

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

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

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

    ```json theme={"system"}
    {
        "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>

<h3 id="update-registry-access">
  레지스트리 액세스 업데이트
</h3>

사용자의 조직 수준 레지스트리 액세스를 부여하거나 철회합니다. 이 권한은 [레지스트리 역할](#add-to-registry)(`registryRoles`)과는 별개입니다. 레지스트리 역할은 사용자에게 권한이 부여된 이후 레지스트리별 권한을 제어합니다.

**Multi-tenant Cloud**와 v0.83.0 이상의 **Dedicated Cloud** 및 **Self-Managed**에서는 `modelsSeat` 또는 `weaveRole`이 `none`이 아닌 사용자에게 기본적으로 레지스트리 액세스 권한이 부여됩니다. Models 시트나 Weave 역할은 그대로 두고 레지스트리 액세스만 철회하려면 `registryAccess`를 `none`으로 설정하세요.

v0.82.0 이하의 **Dedicated Cloud** 및 **Self-Managed**에서 레지스트리 액세스를 철회하려면 [Models 시트 업데이트](#update-models-seat)를 사용하여 `modelsSeat`를 `none`으로 설정하세요. 해당 릴리스에서는 `registryAccess` 속성을 사용할 수 없습니다.

사용자 생성 시 `registryAccess`를 생략하면, 사용자를 조회할 때 API가 해당 사용자의 `modelsSeat` 및 `weaveRole`을 기준으로 실제 액세스 권한을 산정합니다. `registryAccess` 값을 명시하면 이렇게 산정된 값보다 우선 적용됩니다. 청구 전용 조직 역할을 가진 사용자에게는 이 방식으로 레지스트리 액세스 권한이 부여되지 않습니다.

<h4 id="endpoint-14">
  엔드포인트
</h4>

* **URL**: `[HOST-URL]/scim/Users/{id}`
* **메서드**: `PATCH`

<h4 id="parameters-13">
  매개변수
</h4>

| 매개변수 | 유형 | 필수 | 설명 |
| - | - | - | - |
| `id` | string | 예 | 사용자의 고유 ID |
| `op` | string | 예 | `replace` |
| `path` | string | 예 | `registryAccess` |
| `value` | string | 예 | 레지스트리 액세스 권한(`enabled` 또는 `none`) |

<h4 id="example-15">
  예시
</h4>

<Tabs>
  <Tab title="레지스트리 액세스 철회 요청">
    ```bash theme={"system"}
    PATCH /scim/Users/abc
    ```

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

  <Tab title="레지스트리 액세스 철회 응답">
    ```text theme={"system"}
    (Status 200)
    ```

    ```json theme={"system"}
    {
        "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": "none",
        "weaveRole": "full",
        "registryAccess": "none"
    }
    ```
  </Tab>
</Tabs>

<h3 id="assign-team-role">
  팀 역할 부여
</h3>

사용자에게 팀 수준 역할을 부여합니다.

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

<h4 id="endpoint-15">
  엔드포인트
</h4>

* **URL**: `[HOST-URL]/scim/Users/{id}`
* **메서드**: `PATCH`

<h4 id="parameters-14">
  매개변수
</h4>

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

<h4 id="example-16">
  예시
</h4>

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

    ```json theme={"system"}
    {
        "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={"system"}
    (Status 200)
    ```

    ```json theme={"system"}
    {
        "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>

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

사용자에게 레지스트리 수준 역할을 부여하여 레지스트리에 추가합니다.

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

<h4 id="endpoint-16">
  엔드포인트
</h4>

* **URL**: `[HOST-URL]/scim/Users/{id}`
* **메서드**: `PATCH`

<h4 id="parameters-15">
  매개변수
</h4>

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

<h4 id="example-17">
  예시
</h4>

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

    ```json theme={"system"}
    {
        "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={"system"}
    (Status 200)
    ```

    ```json theme={"system"}
    {
        "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>

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

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

<Note>
  이 오퍼레이션은 특정 레지스트리에서 사용자를 제거하며, 조직 수준의 레지스트리 액세스는 철회하지 않습니다. 레지스트리 액세스를 완전히 철회하려면 [레지스트리 액세스 업데이트](#update-registry-access)를 사용하세요.
</Note>

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

<h4 id="endpoint-17">
  엔드포인트
</h4>

* **URL**: `[HOST-URL]/scim/Users/{id}`
* **메서드**: `PATCH`

<h4 id="parameters-16">
  매개변수
</h4>

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

<h4 id="example-18">
  예시
</h4>

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

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

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

    ```json theme={"system"}
    {
        "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={"system"}
    PATCH /scim/Users/abc
    ```

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

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

    ```json theme={"system"}
    {
        "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>

<h2 id="group-resource">
  Group 리소스
</h2>

SCIM group 리소스는 W\&B Team에 매핑됩니다. 이 섹션의 엔드포인트를 사용하면 ID 공급자나 자동화 도구에서 팀을 생성하고, 팀 멤버십을 관리하고, 필요한 경우 팀 수준 저장소를 설정할 수 있습니다. IAM에서 SCIM group을 생성하면 W\&B Team이 생성되어 해당 그룹에 매핑되며, 이후 수행하는 SCIM group 오퍼레이션은 모두 이 팀에 적용됩니다. 팀을 생성할 때 맞춤형 저장소를 설정하려면 요청에 `storageBucket`을 포함하세요.

<h3 id="service-accounts-2">
  서비스 계정
</h3>

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

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

`/Groups` 엔드포인트에서 필터를 사용해 특정 팀을 검색할 수 있습니다.

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

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

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

<h4 id="example-19">
  예시
</h4>

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

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

팀의 고유 ID로 팀 정보를 조회합니다.

<h4 id="endpoint-18">
  엔드포인트
</h4>

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

<h4 id="example-20">
  예시
</h4>

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

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

    ```json theme={"system"}
    {
        "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>

<h3 id="list-teams">
  팀 목록 조회
</h3>

팀 목록을 조회합니다.

<h4 id="endpoint-19">
  엔드포인트
</h4>

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

<h4 id="example-21">
  예시
</h4>

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

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

    ```json theme={"system"}
    {
        "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>

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

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

<h4 id="endpoint-20">
  엔드포인트
</h4>

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

<h4 id="supported-fields">
  지원되는 필드
</h4>

| 필드 | 유형 | 필수 |
| - | - | - |
| `displayName` | string | 예 |
| `members` | Multi-Valued Array | 예 (`value` 하위 필드는 필수이며 사용자 ID에 매핑됨) |
| `storageBucket` | Object | 아니요 |

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

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

W\&B는 팀을 생성하기 전에 버킷이 존재하는지, 그리고 연결할 수 있는지 검증합니다. 검증에 실패하면 SCIM 요청이 실패하며 팀은 생성되지 않습니다.

`provider` 값이 유효하지 않으면 `400 Bad Request`와 함께 허용되는 값 목록이 담긴 SCIM 오류가 반환됩니다.

<h4 id="examples">
  예시
</h4>

다음 예시에서는 맞춤형 저장소 없이 팀을 생성하는 방법과 특정 공급자의 BYOB 저장소로 팀을 생성하는 방법을 보여줍니다. 원하는 저장소 설정에 해당하는 탭을 선택하면 요청 예시를 볼 수 있으며, **응답** 탭을 선택하면 응답 예시를 볼 수 있습니다.

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

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

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

    ```json theme={"system"}
    {
      "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={"system"}
    POST /scim/Groups
    Content-Type: application/scim+json
    ```

    ```json theme={"system"}
    {
      "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={"system"}
    POST /scim/Groups
    Content-Type: application/scim+json
    ```

    ```json theme={"system"}
    {
      "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={"system"}
    POST /scim/Groups
    Content-Type: application/scim+json
    ```

    ```json theme={"system"}
    {
      "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="Response">
    ```text theme={"system"}
    (Status 201)
    ```

    ```json theme={"system"}
    {
        "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>

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

기존 팀의 구성원 목록을 업데이트합니다.

<h4 id="endpoint-21">
  엔드포인트
</h4>

* **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 Team 설정에서 업데이트하세요.
</Note>

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

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

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

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

<h4 id="endpoint-22">
  엔드포인트
</h4>

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

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

    ```json theme={"system"}
    {
        "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={"system"}
    (Status 200)
    ```

    ```json theme={"system"}
    {
        "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>

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

`dev-user2`를 `acme-devs`에 추가합니다.

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

<Tabs>
  <Tab title="Request">
    ```bash theme={"system"}
    PATCH /scim/Groups/{team_id}
    ```

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

  <Tab title="Response">
    ```text theme={"system"}
    (Status 200)
    ```

    ```json theme={"system"}
    {
        "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>

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

`acme-devs`에서 `dev-user2`를 제거합니다.

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

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

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

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

    ```json theme={"system"}
    {
        "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>

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

`acme-devs`에서 모든 사용자를 제거합니다.

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

<Tabs>
  <Tab title="Request">
    ```bash theme={"system"}
    PATCH /scim/Groups/{team_id}
    ```

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

  <Tab title="Response">
    ```text theme={"system"}
    (Status 200)
    ```

    ```json theme={"system"}
    {
        "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>

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

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

<h2 id="role-resource">
  Role 리소스
</h2>

SCIM role 리소스는 W\&B 커스텀 역할에 매핑됩니다. 이 섹션의 엔드포인트를 사용하면 커스텀 역할을 프로그래밍 방식으로 생성하고 관리할 수 있습니다(예: 역할 정의를 액세스 정책과 동기화된 상태로 유지). `/Roles` 엔드포인트는 공식 SCIM 스키마에 속하지 않습니다. W\&B는 W\&B 조직의 커스텀 역할을 자동으로 관리할 수 있도록 `/Roles` 엔드포인트를 별도로 제공합니다.

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

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

<h4 id="endpoint-23">
  엔드포인트
</h4>

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

<h4 id="example-22">
  예시
</h4>

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

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

    ```json theme={"system"}
    {
        "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>

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

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

<h4 id="endpoint-24">
  엔드포인트
</h4>

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

<h4 id="example-23">
  예시
</h4>

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

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

    ```json theme={"system"}
    {
       "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>

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

W\&B 조직에 새 커스텀 역할을 생성합니다.

<h4 id="endpoint-25">
  엔드포인트
</h4>

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

<h4 id="supported-fields-2">
  지원되는 필드
</h4>

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

<h4 id="example-24">
  예시
</h4>

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

    ```json theme={"system"}
    {
        "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={"system"}
    (Status 201)
    ```

    ```json theme={"system"}
    {
        "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>

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

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

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

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

<h5 id="endpoint-26">
  엔드포인트
</h5>

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

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

    ```json theme={"system"}
    {
        "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={"system"}
    (Status 200)
    ```

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

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

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

<h5 id="endpoint-27">
  엔드포인트
</h5>

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

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

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

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

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

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

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

<h4 id="endpoint-28">
  엔드포인트
</h4>

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

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

    ```json theme={"system"}
    {
        "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={"system"}
    (Status 200)
    ```

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

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

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

<h4 id="endpoint-29">
  엔드포인트
</h4>

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

<h4 id="example-25">
  예시
</h4>

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

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

<h2 id="advanced-features">
  고급 기능
</h2>

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

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

SCIM API는 동시 수정 충돌을 방지할 수 있도록 ETag를 사용한 조건부 업데이트를 지원합니다. 이 기능은 여러 관리자나 자동화 시스템이 동일한 리소스를 업데이트할 때 특히 중요합니다. 한 업데이트가 다른 업데이트를 모르는 사이에 덮어쓰는 일을 막아 주기 때문입니다. ETag는 `ETag` 응답 헤더와 `meta.version` 필드로 반환됩니다.

<h4 id="etags">
  ETags
</h4>

ETag를 사용하려면 다음 단계를 따르세요.

1. **현재 ETag 조회**: 리소스를 GET으로 조회할 때 응답에 포함된 ETag 헤더를 확인하세요.
2. **조건부 업데이트**: 업데이트할 때 `If-Match` 헤더에 ETag를 포함하세요.

<h4 id="example-26">
  예시
</h4>

```text theme={"system"}
# 사용자를 조회하고 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` 오류 응답은 리소스를 조회한 후에 해당 리소스가 변경되었음을 의미합니다.

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

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

| 상태 코드 | 설명 |
| - | - |
| `200` | Success(성공) |
| `201` | Created(생성됨) |
| `204` | No Content(삭제 성공) |
| `400` | Bad Request: 매개변수 또는 요청 본문이 잘못됨 |
| `401` | Unauthorized: 인증 실패 |
| `403` | Forbidden: 권한 부족 |
| `404` | Not Found: 리소스가 존재하지 않음 |
| `409` | Conflict: 리소스가 이미 존재함 |
| `412` | Precondition Failed: ETag 불일치 |
| `500` | Internal Server Error(내부 서버 오류) |

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

W\&B는 서로 다른 두 가지 SCIM API 구현을 유지 관리하며, 구현마다 제공되는 기능이 다릅니다. SCIM과 통합하기 전에 다음 표를 검토하여 필요한 오퍼레이션을 사용 중인 배포 유형에서 사용할 수 있는지 확인하세요.

| 기능 | Multi-tenant Cloud | Dedicated Cloud 및 Self-Managed |
| - | - | - |
| 사용자 이메일 업데이트 | - | ✓ |
| 사용자 표시 이름 업데이트 | - | ✓ |
| 사용자 비활성화 | ✓ | ✓ |
| 사용자 재활성화 | - | ✓ |
| 사용자당 여러 이메일 | ✓ | - |
| 생성/업데이트 시 `modelsSeat` 설정 | ✓ | ✓ |
| 생성/업데이트 시 `weaveRole` 설정 | ✓ | ✓ |
| 생성/업데이트 시 `registryAccess` 설정 | ✓ | ✓ |
| `modelsSeat: none`으로 레지스트리 액세스 철회 | - | ✓ |
| `registryAccess: none`으로 레지스트리 액세스 철회 | ✓ | ✓ |

<h2 id="limitations">
  제한 사항
</h2>

SCIM 인테그레이션을 설계할 때는 다음 제약 사항에 유의하세요.

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