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

@@ -3,10 +3,10 @@
## 현재 구조
- Tenant custom schema는 `tenants.config.userSchema` JSONB에 저장한다.
- Tenant custom value는 backend DB의 `users.metadata` JSONB에 저장한다.
- Tenant custom value는 Ory에 저장되지 않거나 Ory API로 필요한 조회가 불가능한 값에 한해 backend DB의 `users.metadata` JSONB read model에 저장한다.
- `isLoginId=true`인 Tenant field 값은 로그인 식별자 처리를 위해 `user_login_ids`에도 동기화한다.
- Ory Kratos traits에는 인증/식별에 필요한 최소 값만 동기화하는 방향으로 정리한다.
- RP custom value는 backend DB의 `rp_user_metadata.metadata` JSONB에 별도 저장한다.
- RP custom value는 Ory에 저장되지 않는 RP 범위 운영 값으로 보고 backend DB의 `rp_user_metadata.metadata` JSONB read model에 별도 저장한다.
## Tenant Custom Field
@@ -50,7 +50,7 @@ RP custom schema는 client metadata의 `customUserSchema`에 저장한다.
}
```
RP custom value는 `rp_user_metadata` 테이블에 저장한다.
RP custom value는 `rp_user_metadata` 테이블에 저장한다. 이 테이블은 Ory SSOT를 대체하지 않는 RP 범위 read model이며, Kratos traits나 token claim output을 원장으로 취급하지 않는다.
```text
client_id text
@@ -90,7 +90,7 @@ PUT payload:
- GIN 인덱스는 backend index manager가 별도 상태로 관리하는 방향을 원칙으로 한다.
- API 요청 처리 중 `CREATE INDEX`를 동기 실행하지 않는다.
## Claim Projection
## Claim Assembly
JWT 또는 userinfo 응답에서는 custom field를 top-level에 풀지 않는다.
Tenant/RP 단위로 묶어서 전달한다.
@@ -120,9 +120,9 @@ Tenant/RP 단위로 묶어서 전달한다.
- `claimEnabled=true` field만 RP claim 후보로 포함한다.
- 긴 JSON 값은 기본적으로 token claim보다 userinfo/profile API 응답에 싣는 방향을 우선한다.
## 한맥가족 Tenant Claim Projection
## 한맥가족 Tenant Claim Assembly
한맥가족(`hanmac-family`) subtree의 tenant claim은 기본 claim과 상세 claim으로 나눈다. 기본 claim은 대표소속 tenant UUID인 `tenant_id`와 전체 소속 목록인 `joined_tenants`이며, RP가 `tenant` claim을 요청하면 tenant별 map 안에 조직 소속 정보를 묶어서 전달한다. 이 정보는 RP가 tenant context를 표시하거나 조직별 기본값을 선택하기 위한 projection이며, 관계형 데이터의 SoT는 PostgreSQL Business DB와 사용자 metadata이다.
한맥가족(`hanmac-family`) subtree의 tenant claim은 기본 claim과 상세 claim으로 나눈다. 기본 claim은 대표소속 tenant UUID인 `tenant_id`와 전체 소속 목록인 `joined_tenants`이며, RP가 `tenant` claim을 요청하면 tenant별 map 안에 조직 소속 정보를 묶어서 전달한다. 이 정보는 RP가 tenant context를 표시하거나 조직별 기본값을 선택하기 위한 claim assembly 결과다. 관계/권한 판단은 Ory Keto를 기준으로 하고, Ory에 저장되지 않거나 조회가 불가능한 표시/검색 metadata만 Backend read model에서 보강한다.
기본 claim 예시는 다음과 같다.
@@ -235,7 +235,7 @@ Issue #775 구현 결과 기준으로 RP가 `tenant` claim을 요청했을 때
- 대표소속 결정은 명시적 `tenant_id`, `additionalAppointments``representative/isPrimary/primary=true`, 가장 먼저 등록된 소속 순서로 적용한다.
- 생성 시 소속 tenant가 하나도 없으면 PERSONAL tenant를 자동 생성하고, 해당 tenant를 `tenant_id``joined_tenants`에 포함한다.
- RP/client tenant context는 대표소속 `tenant_id`를 덮어쓰지 않는다.
- tenant별 namespaced traits map이 없어도 `tenant_id` 또는 `additionalAppointments[].tenantId`를 기준으로 projection 항목을 만들 수 있다.
- tenant별 namespaced traits map이 없어도 `tenant_id` 또는 `additionalAppointments[].tenantId`를 기준으로 claim assembly 항목을 만들 수 있다.
- 멀티 소속이면 기본 claim의 `joined_tenants`에 모든 소속 tenant를 넣는다. `tenant` claim 요청 시에는 `tenants`에도 모든 소속 tenant 상세를 넣고, `lead_tenants`에는 lead tenant만 넣는다.
- token 크기 보호를 위해 전체 조직도나 긴 custom JSON은 claim에 싣지 않고 profile/userinfo API 또는 backend API 응답으로 분리한다.
- RP는 `joined_tenants`로 전체 소속을 읽고, `lead_tenants`로 lead tenant를 빠르게 식별한다. 상세 표시는 `tenants[tenant_id]` 또는 `tenants[joined_tenants[n]]``ancestors`를 조합한다.