forked from baron/baron-sso
docs: enrich tenant policy with core architecture principles for integrity and OIDC pooling
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
이 문서는 Baron SSO 시스템 내 B2C(개인)부터 B2B(단일기업), B2B2B(그룹사) 및 사내 조직도(`UserGroup`)에 이르는 모든 격리 공간과 권한 상속을 다루는 **다형성 테넌트(Polymorphic Tenant)**의 공식 정책을 정의합니다.
|
||||
|
||||
이 정책은 기존의 단순 `Tenant` 및 `UserGroup` 모델을 발전시켜, Ory Kratos(Identity), PostgreSQL(Business), Ory Keto(ReBAC) 3개의 분산 시스템 간 역할을 명확히 하고 데이터 정합성을 강제합니다.
|
||||
연구 결과에 기반하여, 단순한 B2C 수준을 넘어 복잡한 테넌트 생태계를 안정적이고 고성능으로 지원하기 위해 **외부 DB 의무 채택, 트랜잭셔널 아웃박스 동기화, Keto 기반 인가 백본, 논리적 다중 테넌트 OIDC 관리**라는 4대 핵심 아키텍처 원칙을 준수합니다.
|
||||
|
||||
---
|
||||
|
||||
@@ -22,10 +22,11 @@
|
||||
- 시스템의 모든 자원(예: RelyingParty, 앱)은 반드시 특정 `Tenant`가 소유(`manage`)합니다.
|
||||
- 그러나 자원의 소유권과 **누가 접근할 수 있는가(가시성, `access`)는 별개**입니다. 내부망용 앱(Private)과 대국민 서비스(Public)를 동일한 기업(Tenant)이 동시에 소유하고 제어할 수 있습니다.
|
||||
|
||||
### 1.4 단일 진실 공급원 분리 (Separation of SoT)
|
||||
### 1.4 외부 백엔드 데이터베이스 아키텍처 의무 채택 (Separation of SoT)
|
||||
사용자 데이터를 Kratos의 내부 트레이트(Traits)에 무분별하게 저장하는 것은 안티 패턴입니다. 이는 토큰 비대화와 쿼리 성능 저하를 초래합니다.
|
||||
- **Kratos (Identity):** "누구인가?" (인증, 이메일, 패스워드 등 순수 식별 정보). 테넌트, 직급 등 관계형 데이터는 절대 보관하지 않습니다.
|
||||
- **PostgreSQL (Business):** "어디에 속하며 조직 구조는 어떠한가?" (직급, 조직도, 테넌트 설정 등).
|
||||
- **Keto (ReBAC):** "무엇을 할 수 있는가?" (권한 및 상속).
|
||||
- **Keto (ReBAC Authorization Backbone):** "무엇을 할 수 있는가?" (권한 및 상속).
|
||||
|
||||
---
|
||||
|
||||
@@ -43,9 +44,9 @@
|
||||
|
||||
---
|
||||
|
||||
## 3. ReBAC 권한 상속 및 관계 튜플 (Keto Tuples)
|
||||
## 3. 중앙집중형 인가 백본 (Keto ReBAC Tuples)
|
||||
|
||||
이전에는 `UserGroup` 네임스페이스가 존재했으나, 이제 모든 권한 검증은 오직 `Tenant` 네임스페이스 내에서 처리됩니다.
|
||||
복잡한 다단계 B2B2B 조직도 내에서의 상속 권한을 외부 RDBMS 논리만으로 실시간 검증하는 것은 과부하를 초래합니다. 따라서 조직도 변경 시 해당 데이터를 즉시 Keto의 관계 튜플로 변환하여 전송하고, **인가 검증(Check)은 초고속 병렬 처리가 가능한 Keto 엔진으로 오프로딩**합니다.
|
||||
|
||||
### 3.1 조직장(Leader)과 어드민(Admin) 상속
|
||||
특정 부서(테넌트)의 그룹장(`owners`)으로 임명되면, 해당 부서 및 그 하위 부서의 최고 관리자(`admins`) 권한을 자동으로 상속받습니다.
|
||||
@@ -53,7 +54,7 @@
|
||||
- **자동 상속 룰:** `Tenant:<조직ID>#admins@Tenant:<조직ID>#owners`
|
||||
|
||||
### 3.2 계층 간 권한 상속 (Hierarchy)
|
||||
지주사(COMPANY_GROUP) $\rightarrow$ 법인(COMPANY) $\rightarrow$ 사내조직(USER_GROUP) 간의 상속은 모두 `parents` 튜플을 사용합니다.
|
||||
지주사 $\rightarrow$ 법인 $\rightarrow$ 사내조직 간의 상속은 모두 `parents` 튜플을 사용합니다.
|
||||
- **계층 설정:** `Tenant:<하위ID>#parents@Tenant:<상위ID>`
|
||||
- **자동 상속 룰:** 상위 테넌트의 `admins`는 하위 테넌트의 `manage` 및 `view` 권한을 모두 가집니다.
|
||||
|
||||
@@ -131,24 +132,32 @@ graph TD
|
||||
|
||||
---
|
||||
|
||||
## 5. 분산 시스템 정합성 강제 정책 (Data Consistency Check)
|
||||
## 5. 지능형 프록시를 통한 논리적 다중 테넌트 OIDC 관리
|
||||
|
||||
인증(Kratos), 비즈니스 로직(PG), 권한(Keto)이 어긋나지 않도록 다음의 안전 장치를 반드시 구현해야 합니다.
|
||||
인프라 비용 팽창을 막기 위해 테넌트별로 Hydra(OAuth2/OIDC) 클러스터를 물리적으로 복제하는 것은 지양합니다.
|
||||
|
||||
### 5.1 트랜잭셔널 아웃박스 패턴 (Transactional Outbox)
|
||||
- **목적:** 백엔드 DB에는 저장되었으나, 일시적인 네트워크 장애로 인해 Keto(ReBAC)에 권한이 저장되지 않는 '부분 실패(Partial Failure)' 방지.
|
||||
- **방식:** DB에 새로운 테넌트(`UserGroup` 등) 생성 시, 동일 DB 트랜잭션 내에서 `keto_outbox` 테이블에 튜플 이벤트를 함께 저장합니다. 이후 Background Worker가 이를 안전하게 Keto로 동기화(재시도 보장)합니다.
|
||||
### 5.1 Logical Pooling for OAuth2
|
||||
- 모든 테넌트(`COMPANY`, `PERSONAL`)는 소수의 공유된 Hydra 클러스터를 사용합니다.
|
||||
- Hydra 클러스터 앞단에 도메인 및 헤더를 재작성하는 지능형 프록시(API Gateway)를 배치하여, 테넌트별로 물리적으로 분리된 것과 같은 라우팅 효과를 제공합니다.
|
||||
|
||||
### 5.2 삭제 정책 연동 (Delete Cascade)
|
||||
- **보안 원칙 (즉시 회수):** 백엔드에서 테넌트나 유저를 Soft Delete(`deleted_at`) 처리하는 즉시, Outbox를 통해 **Keto의 관련된 모든 튜플을 Hard Delete**하여 권한을 즉각적으로 회수합니다.
|
||||
- **Kratos 계정 삭제:** 사용자가 계정을 영구 탈퇴할 경우, Kratos에서 데이터가 지워지기 직전에 백엔드로 Webhook을 전송하여 Keto 권한 및 로컬 `users` 테이블의 프로필 데이터를 먼저 비우도록 연동합니다.
|
||||
### 5.2 동적 클레임 주입 (Dynamic Claim Injection)
|
||||
- 로그인 및 동의(Consent) 흐름은 전적으로 외부 백엔드 데이터베이스(Business SoT)가 주도합니다.
|
||||
- 백엔드는 요청된 클라이언트(RP)의 테넌트 맥락(Context)을 파악하고, 유저가 속한 현재 조직 정보 및 권한(Role)을 Hydra에 전달하여 **ID Token의 Custom Claim으로 동적 주입**합니다.
|
||||
|
||||
### 5.3 Kratos-Backend 실시간 동기화 (Webhooks)
|
||||
- Kratos에서의 회원 가입(`after_registration`) 및 정보 변경(`after_settings`) 발생 시, 즉시 Webhook을 발생시켜 Backend의 `users` 테이블(프로필 로컬 캐시)을 Upsert 합니다.
|
||||
---
|
||||
|
||||
### 5.4 정기 대사 스크립트 (Reconciliation Cron Job)
|
||||
- 매일 1회 이상 배치 작업을 돌려 분산 시스템 간 엣지 케이스 오류를 복구합니다.
|
||||
- **검증 항목:**
|
||||
1. Keto에 남아있는 고아 튜플(Orphaned Tuples) 검출 및 자동 삭제.
|
||||
2. DB의 `user_groups` 멤버십에는 존재하나 Keto 튜플에서 누락된 권한 색출 및 복원.
|
||||
3. Kratos와 Backend 간 유저 ID 매핑 상태 일치 여부 스캔.
|
||||
## 6. 분산 시스템 동기화 무결성 확보 (Data Consistency)
|
||||
|
||||
Kratos 웹훅 통신 지연이나 이중 쓰기(Dual-Write) 오류로 인한 '고아 레코드(Ghost Identity)'를 원천 차단해야 합니다.
|
||||
|
||||
### 6.1 빠른 제어권 반환 및 비동기 처리 혼합 (Kratos $\rightarrow$ DB)
|
||||
- **가입 웹훅(after_registration):** Kratos에서 웹훅 요청이 오면, 백엔드는 국소 DB 트랜잭션을 열어 최소한의 필수 식별자 데이터만 `users` 테이블에 커밋하고 **즉각적으로 200 OK를 응답하여 Kratos에 제어권을 반환**합니다. (가입 중단 방지)
|
||||
- 웰컴 이메일 발송, 초기 조직도 프로비저닝 등 무거운 작업은 즉시 처리하지 않고 메시지 큐(Message Queue)나 비동기 워커로 넘겨 후속 처리합니다.
|
||||
|
||||
### 6.2 트랜잭셔널 아웃박스 패턴 (DB $\rightarrow$ Keto)
|
||||
- 백엔드 로직에 의해 테넌트나 권한이 변경될 때, Keto API를 직접 호출하면 네트워크 오류 시 부분 실패(Partial Failure)가 발생할 수 있습니다.
|
||||
- 이를 방지하기 위해 DB 커밋 시 동일 트랜잭션 내에서 `keto_outbox` 테이블에 튜플 변경 이벤트를 기록합니다. 이후 CDC(Change Data Capture) 로직이나 릴레이 워커를 통해 비동기로 시스템 간 동기화를 진행하여 응답 속도와 정합성을 동시에 달성합니다.
|
||||
|
||||
### 6.3 삭제 정책 (Cascade) 및 정기 대사
|
||||
- **즉시 회수:** 백엔드 DB에서 Soft Delete(`deleted_at`)가 발생하면, Outbox 워커는 지연 없이 즉각적으로 Keto의 튜플을 Hard Delete 합니다.
|
||||
- **정기 대사 (Reconciliation):** Kratos(Identity), PostgreSQL(DB), Keto(ReBAC) 3자 간의 불일치(고아 튜플, 누락된 멤버십 등)를 매일 1회 이상 배치 크론 잡을 통해 능동적으로 색출하고 자동 복구/삭제합니다.
|
||||
Reference in New Issue
Block a user