Search K
SCIM 프로비저닝
SnapOtter는 자동화된 사용자 및 그룹 프로비저닝을 위해 SCIM 2.0(System for Cross-domain Identity Management)을 구현합니다. 아이덴티티 공급자가 사용자 계정을 생성, 업데이트, 비활성화, 재활성화하고 그룹 멤버십을 자동으로 동기화할 수 있습니다.
엔터프라이즈 기능
SCIM 프로비저닝에는 scim 기능이 포함된 엔터프라이즈 라이선스가 필요합니다. team 플랜에서는 사용할 수 없습니다. 이 기능이 없으면 모든 SCIM 엔드포인트(디스커버리 제외)는 403을 반환합니다.
사전 요구 사항
- 공개 URL에서 접근할 수 있는 실행 중인 SnapOtter 인스턴스
scim기능이 포함된 엔터프라이즈 라이선스 키- SnapOtter에 대한 관리자 접근 권한(SCIM 토큰을 생성하거나 취소하려면
users:manage권한이 필요합니다) - 아이덴티티 공급자의 프로비저닝 설정에 대한 관리자 접근 권한
빠른 시작
- SCIM 베어러 토큰을 생성합니다:
bash
curl -X POST https://photos.example.com/api/v1/enterprise/scim/token \
-H "Cookie: snapotter-session=YOUR_SESSION" \
-H "Content-Type: application/json"응답에 토큰이 포함되어 있습니다. 즉시 저장하세요. 다시 조회할 수 없습니다.
json
{
"token": "a1b2c3d4e5f6...",
"message": "Save this token - it cannot be retrieved again"
}- 아이덴티티 공급자에서 다음 값으로 SCIM 프로비저닝을 구성합니다:
- Base URL:
https://photos.example.com/api/v1/scim/v2 - 인증: 베어러 토큰(1단계에서 생성한 토큰을 붙여넣기)
- Base URL:
인증
SCIM 엔드포인트는 사용자 세션 및 API 키와는 별도인 전용 베어러 토큰을 사용합니다.
토큰 생성
POST /api/v1/enterprise/scim/token 는 새 SCIM 토큰을 생성합니다. 이 엔드포인트에는 users:manage 권한이 있는 유효한 세션이 필요합니다.
토큰은 정확히 한 번만 평문으로 반환됩니다. SnapOtter는 scrypt 해시만 저장합니다. 토큰을 분실하면 취소하고 새로 생성하세요.
한 번에 하나의 SCIM 토큰만 활성화됩니다. 새 토큰을 생성하면 이전 토큰이 대체됩니다.
토큰 취소
DELETE /api/v1/enterprise/scim/token 는 현재 SCIM 토큰을 취소합니다. 이 엔드포인트에도 users:manage 권한이 필요합니다.
속도 제한
SCIM 엔드포인트는 토큰당 분당 1000개 요청으로 속도가 제한됩니다. 이 한도를 초과하면 HTTP 429를 반환합니다.
지원되는 리소스
| SCIM 리소스 | SnapOtter 개념 | 생성 | 읽기 | 업데이트 | 삭제 |
|---|---|---|---|---|---|
| User | 사용자 계정 | 예 | 예 | 예 | 소프트 삭제 |
| Group | 팀 | 예 | 예 | 예 | 예 |
WARNING
SCIM 그룹은 역할이 아니라 SnapOtter 팀에 매핑됩니다. SCIM은 사용자의 역할을 설정할 수 없습니다. SCIM을 통해 생성된 모든 사용자에게는 user 역할이 할당됩니다. 사용자의 역할을 변경하려면 SnapOtter 관리자 UI를 사용하세요.
사용자 작업
사용자 생성
POST /api/v1/scim/v2/Users
authProvider 를 scim 로 설정하고 user 역할을 부여한 새 사용자 계정을 생성합니다. 사용자는 Default 팀에 할당됩니다. active 가 false 이면 역할이 대신 disabled 로 설정됩니다.
필수 속성: userName. 선택 속성: externalId, emails, active(기본값 true).
사용자 목록 조회 및 필터링
GET /api/v1/scim/v2/Users
사용자의 페이지네이션된 목록을 반환합니다. startIndex 및 count 쿼리 파라미터를 지원합니다(페이지당 최대 200개 결과).
필터링은 다음 속성에 대해 eq(같음)만 지원합니다:
userName eq "jane"externalId eq "ext-12345"
다른 필터 연산자와 속성은 HTTP 400을 반환합니다.
사용자 조회
GET /api/v1/scim/v2/Users/:id
SnapOtter 사용자 ID로 단일 사용자를 반환합니다.
사용자 교체
PUT /api/v1/scim/v2/Users/:id
사용자의 속성을 교체합니다. userName, externalId, emails, active 를 지원합니다. 사용자 이름 변경 시 충돌 여부를 확인합니다(새 사용자 이름이 다른 사용자가 사용 중이면 409).
사용자 패치
PATCH /api/v1/scim/v2/Users/:id
SCIM PatchOp를 사용한 부분 업데이트. 지원되는 작업:
| 작업 | 경로 |
|---|---|
replace | active, userName, externalId, emails, emails[type eq "work"].value, name.formatted, displayName |
add | replace 와 동일 |
remove | externalId, emails |
name.formatted 및 displayName 경로는 호환성을 위해 허용되지만 영속적인 효과는 없습니다(SnapOtter는 별도의 표시 이름을 저장하지 않습니다).
값이 없는 replace 작업(값이 path 없이 객체인 경우)도 userName, externalId, emails, active 키와 함께 지원됩니다.
사용자 비활성화(소프트 삭제)
DELETE /api/v1/scim/v2/Users/:id
SnapOtter는 SCIM을 통해 사용자를 하드 삭제하지 않습니다. 대신 DELETE는 소프트 비활성화를 수행합니다:
- 사용자의 역할이 현재 값(예:
editor)에서disabled:editor으로 변경되어 원래 역할을 보존합니다. - 사용자의 비밀번호가 지워집니다.
- 모든 활성 세션이 취소됩니다.
- 모든 API 키가 취소됩니다.
사용자는 더 이상 로그인하거나 어떤 API 키도 사용할 수 없습니다. 사용자의 데이터(파일, 기록)는 유지됩니다.
사용자 재활성화
이전에 비활성화된 사용자를 재활성화하려면 active: true 값과 함께 PUT 또는 PATCH 요청을 보냅니다. SnapOtter는 비활성화 이전의 원래 역할을 복원합니다(예: disabled:editor 가 다시 editor 이 됩니다). 원래 역할을 확인할 수 없으면 user 로 대체됩니다.
예시: PATCH를 통한 비활성화 및 재활성화
json
// Deactivate
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [
{ "op": "replace", "path": "active", "value": false }
]
}
// Reactivate
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [
{ "op": "replace", "path": "active", "value": true }
]
}그룹 작업
SCIM 그룹은 SnapOtter 팀에 매핑됩니다. 그룹을 생성하면 팀이 생성됩니다. 그룹 멤버십은 사용자가 속한 팀을 제어합니다.
그룹 생성
POST /api/v1/scim/v2/Groups
필수: displayName. 선택: members({ value: userId } 의 배열).
그룹 목록 조회 및 필터링
GET /api/v1/scim/v2/Groups
필터링은 displayName eq "..." 만 지원합니다. startIndex 및 count 로 페이지네이션됩니다(페이지당 최대 200개 결과).
그룹 조회
GET /api/v1/scim/v2/Groups/:id
그룹 교체
PUT /api/v1/scim/v2/Groups/:id
그룹 이름과 전체 멤버십 목록을 교체합니다. 새 목록에 없는 기존 멤버는 Default 팀으로 이동됩니다.
그룹 패치
PATCH /api/v1/scim/v2/Groups/:id
다음 작업을 지원합니다:
| 작업 | 경로 | 효과 |
|---|---|---|
add | members | 사용자를 팀에 추가 |
remove | members[value eq "userId"] | 사용자를 Default 팀으로 이동 |
replace | displayName | 팀 이름 변경 |
replace | members | 모든 멤버 교체(제거된 멤버는 Default 팀으로 이동) |
그룹 삭제
DELETE /api/v1/scim/v2/Groups/:id
팀을 삭제합니다. 삭제된 팀의 모든 멤버는 Default 팀으로 이동됩니다. 사용자는 비활성화되거나 삭제되지 않습니다.
IdP 설정
Okta
- Okta 관리자 콘솔에서 SnapOtter 애플리케이션을 엽니다(또는 새로 생성합니다).
- Provisioning 탭으로 이동하여 Configure API Integration을 클릭합니다.
- Enable API Integration을 체크하고 다음을 입력합니다:
- Base URL:
https://photos.example.com/api/v1/scim/v2 - API Token: 위에서 생성한 SCIM 베어러 토큰
- Base URL:
- Test API Credentials를 클릭한 다음 Save를 클릭합니다.
- Provisioning > To App에서 다음을 활성화합니다:
- Create Users
- Update User Attributes
- Deactivate Users
- Push Groups에서 어떤 Okta 그룹을 SnapOtter 팀으로 동기화할지 구성합니다.
Azure AD / Entra ID
- Azure 포털에서 SnapOtter 엔터프라이즈 애플리케이션으로 이동합니다.
- Provisioning으로 이동하여 Provisioning Mode를 Automatic으로 설정합니다.
- Admin Credentials에서 다음을 입력합니다:
- Tenant URL:
https://photos.example.com/api/v1/scim/v2 - Secret Token: 위에서 생성한 SCIM 베어러 토큰
- Tenant URL:
- Test Connection을 클릭한 다음 Save를 클릭합니다.
- Mappings에서 사용자 및 그룹 속성 매핑을 구성합니다. 기본값이 대개 잘 작동하지만,
userName가 원하는 대로userPrincipalName또는mail로 매핑되는지 확인하세요. - Provisioning Status를 On으로 설정하고 저장합니다.
Azure는 고정된 동기화 주기(일반적으로 40분마다)로 사용자와 그룹을 프로비저닝합니다.
디스커버리 엔드포인트
다음 세 엔드포인트는 인증 없이 사용할 수 있으며 SCIM 서버의 기능을 설명합니다:
| 엔드포인트 | 설명 |
|---|---|
GET /api/v1/scim/v2/ServiceProviderConfig | 서버 기능 및 지원되는 특성 |
GET /api/v1/scim/v2/Schemas | User 및 Group 스키마 정의 |
GET /api/v1/scim/v2/ResourceTypes | 사용 가능한 리소스 유형(User, Group) |
ServiceProviderConfig 는 다음 기능을 알립니다:
| 특성 | 지원 여부 |
|---|---|
| Patch | 예 |
| Bulk | 아니오 |
| Filter | 예(최대 200개 결과, eq 연산자만) |
| Change password | 아니오 |
| Sort | 아니오 |
| ETag | 아니오 |
제한 사항
- 필터링:
eq연산자만 지원됩니다. 복합 필터,and/or연산자,co(포함),sw(로 시작)는 구현되지 않았습니다. - 벌크 작업: 지원되지 않습니다.
- Sort 및 ETag: 지원되지 않습니다.
- 역할: SCIM은 SnapOtter 역할을 할당할 수 없습니다. 프로비저닝된 모든 사용자는
user역할을 받습니다. - MAX_USERS:
MAX_USERS환경 변수 한도는 SCIM 사용자 생성에 적용되지 않습니다. 사용자 수를 제한하려면 IdP에서 할당을 관리하세요. - 단일 토큰: 한 번에 하나의 SCIM 토큰만 활성화할 수 있습니다. 여러 IdP가 SCIM 접근이 필요한 경우 토큰을 공유해야 합니다.
- 그룹은 팀: SCIM 그룹은 역할이나 권한 그룹이 아니라 팀에 대응됩니다.
문제 해결
403 "SCIM provisioning requires an enterprise license with the scim feature"
라이선스에 scim 기능이 포함되어 있지 않거나 라이선스가 구성되지 않았습니다. SCIM에는 엔터프라이즈 플랜 라이선스가 필요합니다. SNAPOTTER_LICENSE_KEY 가 설정되어 있고 라이선스에 scim 기능이 포함되어 있는지 확인하세요.
401 "Bearer token required"
SCIM 요청에 Authorization: Bearer <token> 헤더가 포함되지 않았습니다. IdP의 프로비저닝 구성을 확인하세요.
401 "Invalid token"
토큰이 저장된 해시와 일치하지 않습니다. 토큰이 취소되고 다시 생성된 경우 발생합니다. IdP의 프로비저닝 설정에서 토큰을 업데이트하세요.
401 "SCIM not configured"
아직 SCIM 토큰이 생성되지 않았습니다. POST /api/v1/enterprise/scim/token 엔드포인트를 사용해 토큰을 생성하세요.
409 "User already exists" / "userName already taken"
동일한 사용자 이름을 가진 사용자가 이미 존재합니다. IdP가 실패한 생성을 재시도할 때 발생할 수 있습니다. SnapOtter 관리자 패널에서 중복된 사용자 이름을 확인하세요.
429 "SCIM rate limit exceeded"
IdP가 분당 1000개를 초과하는 요청을 보내고 있습니다. 일반적으로 대규모 초기 동기화 중에 발생합니다. 대부분의 IdP는 속도 제한 창이 재설정된 후 자동으로 재시도합니다. 문제가 지속되면 IdP의 프로비저닝 동기화 간격을 확인하세요.
사용자가 프로비저닝 해제되었지만 UI에서 제거되지 않음
SCIM DELETE는 소프트 비활성화입니다. 비활성화된 사용자는 여전히 비활성 상태로 관리자 사용자 목록에 표시됩니다. 이는 데이터를 보존하기 위한 의도된 설계입니다. 해당 사용자의 역할은 disabled:<original-role> 로 표시됩니다.
