요약
SCIM PUT /scim/v2/Users/{id}의 tombstone 검사와 계정 병합의 tombstone 기록/비활성화가 동시에 실행되면, 검사 통과 후 수행된 SCIM 교체가 병합 포인터를 덮어쓰고 계정을 재활성화할 수 있습니다. 사용자 ID 기준의 공유 직렬화(분산 락 또는 동등한 원자적 메커니즘)를 도입하여 이 경쟁 조건을 제거합니다.
배경 및 근거
현재 SCIM 교체 경로는 tombstone 속성 조회와 Keycloak 사용자 교체를 별도 Admin API 요청으로 수행합니다. 두 요청 사이에 병합이 발생할 수 있으므로, 현재 보호는 비동시 요청에 대해서는 효과적이지만 동시 병합에 대한 TOCTOU 구간은 남아 있습니다.
제약 사항
- 이 서비스는 현재 분산 락 백엔드를 제공하지 않는 stateless FastAPI shim입니다.
- Keycloak Admin API의
PUT /users/{id}는 ETag/If-Match 또는 optimistic-version 기반 조건부 갱신을 제공하지 않습니다.
- 따라서 단순 재조회나
scim.py의 국소 수정으로는 해결할 수 없으며, SCIM 교체와 병합 경로 모두를 포괄하는 설계 변경이 필요합니다.
영향 범위
services/account_unification/app/scim.py: SCIM replace_user의 tombstone 검사 및 사용자 교체 흐름
services/account_unification/app/service.py: 계정 병합 시 tombstone 기록 및 사용자 비활성화 흐름
- 필요 시 잠금/원자성 제공을 위한 서비스 인프라 및 구성
요구 사항
- 사용자 ID를 키로 하는 공유 동기화 메커니즘 또는 동등한 원자적 처리 방식을 설계하고 도입합니다.
- SCIM
replace_user가 tombstone 검사부터 replace_user 쓰기까지 해당 메커니즘으로 보호되도록 합니다.
- 계정 병합 경로가 동일한 메커니즘을 사용하여 대상 사용자의 tombstone 기록과 비활성화를 직렬화하도록 합니다.
- 검사 통과 후 동시 병합이 발생해도 SCIM 쓰기가 tombstone 포인터를 덮어쓰거나 병합된 계정을 재활성화할 수 없음을 검증하는 동시성 회귀 테스트를 추가합니다.
- 장애, 타임아웃, 락 획득 실패 시의 동작과 운영상 요구되는 인프라를 문서화합니다.
관련 링크
요청자: @seonghobae
요약
SCIM
PUT /scim/v2/Users/{id}의 tombstone 검사와 계정 병합의 tombstone 기록/비활성화가 동시에 실행되면, 검사 통과 후 수행된 SCIM 교체가 병합 포인터를 덮어쓰고 계정을 재활성화할 수 있습니다. 사용자 ID 기준의 공유 직렬화(분산 락 또는 동등한 원자적 메커니즘)를 도입하여 이 경쟁 조건을 제거합니다.배경 및 근거
현재 SCIM 교체 경로는 tombstone 속성 조회와 Keycloak 사용자 교체를 별도 Admin API 요청으로 수행합니다. 두 요청 사이에 병합이 발생할 수 있으므로, 현재 보호는 비동시 요청에 대해서는 효과적이지만 동시 병합에 대한 TOCTOU 구간은 남아 있습니다.
제약 사항
PUT /users/{id}는 ETag/If-Match또는 optimistic-version 기반 조건부 갱신을 제공하지 않습니다.scim.py의 국소 수정으로는 해결할 수 없으며, SCIM 교체와 병합 경로 모두를 포괄하는 설계 변경이 필요합니다.영향 범위
services/account_unification/app/scim.py: SCIMreplace_user의 tombstone 검사 및 사용자 교체 흐름services/account_unification/app/service.py: 계정 병합 시 tombstone 기록 및 사용자 비활성화 흐름요구 사항
replace_user가 tombstone 검사부터replace_user쓰기까지 해당 메커니즘으로 보호되도록 합니다.관련 링크
요청자: @seonghobae