1
0
forked from baron/baron-sso

custom claim 권한체크 확인

This commit is contained in:
2026-06-11 08:29:25 +09:00
parent 839ca9d407
commit 4d77060b5d
79 changed files with 4268 additions and 670 deletions

View File

@@ -1,14 +1,14 @@
# 사용자 projection 가시성 감사 보고서
# 사용자 가시성 감사 보고서
작성 시각: 2026-06-08 16:55 KST
관련 이슈:
- #1035: adminfront 사용자 레지스트리 total이 Kratos 250건 제한으로 잘못 표시됨
- #1036: 사용자 projection 가시성 영향 범위 검증 및 WORKS 비교 표 row count 표시
- #1036: 사용자 가시성 영향 범위 검증 및 WORKS 비교 표 row count 표시
## 결론
`총 250명` 표시는 단순 UI 문제가 아니라, Kratos partial list를 full snapshot처럼 처리한 projection 동기화 버그였습니다.
`총 250명` 표시는 단순 UI 문제가 아니라, Kratos partial list를 full snapshot처럼 처리한 legacy sync 버그였습니다.
현재 로컬 DB와 API는 다음 상태입니다.
@@ -16,7 +16,7 @@
| --- | ---: | --- |
| users 전체 | 2,114 | `deleted_at` 포함 전체 row |
| visible users | 1,917 | `deleted_at IS NULL`, adminfront/orgfront 사용자 목록 기준 |
| soft-deleted users | 197 | 사용자 삭제 또는 과거 projection 문제로 숨겨진 row |
| soft-deleted users | 197 | 사용자 삭제 또는 과거 legacy sync 문제로 숨겨진 row |
| CSV 원본 줄 수 | 1,887 | 헤더 포함 |
| CSV 실제 데이터 행 | 1,886 | 헤더 제외 |
| 이번 import 사용자 | 1,886 | 모두 DB 매칭, 모두 visible |
@@ -33,8 +33,8 @@
보고 파일 위치:
- `reports/user-projection-visibility-audit-20260608-1645/existing_users_not_in_saman_import.csv`
- `reports/user-projection-visibility-audit-20260608-1645/imported_users_missing_or_soft_deleted.csv`
- `reports/user-visibility-audit-20260608-1645/existing_users_not_in_saman_import.csv`
- `reports/user-visibility-audit-20260608-1645/imported_users_missing_or_soft_deleted.csv`
파일 내용:
@@ -100,9 +100,9 @@ soft-deleted 기존 사용자 197명과 WORKS comparison `baronId`를 대조한
이번 문제는 단일 UI 카운트 문제가 아니라 다음 경계가 한꺼번에 얽힌 문제였습니다.
1. Kratos identity list는 partial list인데 backend projection sync가 full snapshot으로 처리했습니다.
2. projection sync가 local DB soft-delete까지 수행해 사용자 가시성 자체를 손상시켰습니다.
3. adminfront 사용자 목록, orgfront 조직도, WORKS comparison이 모두 사용자 projection을 다른 방식으로 소비하고 있었습니다.
1. Kratos identity list는 partial list인데 legacy backend sync가 full snapshot으로 처리했습니다.
2. legacy sync가 Backend DB soft-delete까지 수행해 사용자 가시성 자체를 손상시켰습니다.
3. adminfront 사용자 목록, orgfront 조직도, WORKS comparison이 모두 사용자 데이터를 다른 방식으로 소비하고 있었습니다.
4. WORKS comparison은 사용자 목록이 아니라 Baron/WORKS 양쪽 차이를 보여주는 비교 화면이라 total 의미가 달랐습니다.
5. 운영자가 partial data인지 바로 볼 수 있도록 WORKS 표 row count가 필요했습니다.
@@ -110,14 +110,14 @@ soft-deleted 기존 사용자 197명과 WORKS comparison `baronId`를 대조한
현재 구조는 다음과 같습니다.
- Ory/Kratos -> backend projection sync: 현재 `ListIdentities()` partial 조회입니다. offset/cursor 전체 순회가 아닙니다.
- backend projection -> adminfront 사용자 목록: `cursor`가 있으면 cursor pagination, 없으면 offset pagination을 받습니다. adminfront는 infinite query로 `nextCursor`를 사용합니다.
- backend projection -> orgfront 조직도/picker: 현재 `limit=5000&offset=0` 단일 offset 조회니다.
- Ory/Kratos -> Backend identity mirror warmup: `ListIdentities()` partial 조회를 전체 snapshot으로 취급하면 안 됩니다. 전체 수집은 pagination을 끝까지 따라가야 합니다.
- Backend -> adminfront 사용자 목록: `cursor`가 있으면 cursor pagination, 없으면 offset pagination을 받습니다. adminfront는 infinite query로 `nextCursor`를 사용합니다.
- Backend -> orgfront 조직도/picker: Redis orgchart snapshot 또는 Backend cursor API를 사용해야 하며 `limit=5000&offset=0` 단일 offset 조회는 금지합니다.
- WORKS comparison: backend가 비교 결과 배열을 만들어 내려주고, adminfront가 검색/필터 후 화면 row를 표시합니다.
## 재발 방지 조치
- 사용자 목록 API는 Kratos가 아니라 local projection DB를 primary source로 사용합니다.
- Kratos partial list에 없는 사용자를 projection sync에서 삭제하지 않도록 수정했습니다.
- 사용자 목록 API는 Backend가 Ory-warmed Redis cache와 허용된 read model을 조합해 cursor로 제공합니다.
- Kratos partial list에 없는 사용자를 legacy sync에서 삭제하지 않도록 수정했습니다.
- WORKS comparison에서 soft-deleted local user가 들어와도 comparison row로 노출되지 않도록 방어 테스트와 로직을 추가했습니다.
- WORKS comparison 표에 `표시 N / 전체 M` row count를 표시했습니다.