forked from baron/baron-sso
3.5 KiB
3.5 KiB
Tenant 정책 (Tenant Policy)
1. 개요 (Overview)
Baron SSO는 Multi-Tenancy를 지원하여, 단일 인스턴스에서 여러 조직(Tenant)의 데이터와 사용자를 격리하여 관리할 수 있다. 이 문서는 테넌트의 계층 구조, 리소스 소유권, 데이터 모델링 및 보안 정책을 정의한다.
2. 계층 구조 및 제약 (Hierarchy & Constraints)
2.1 계층 제한 (Depth Limit)
복잡성을 통제하기 위해 테넌트 계층은 **최대 2 Depth (1단계 깊이)**까지만 허용한다.
- Root Tenant (Level 1): 최상위 조직 (예: 본사, 고객사 A)
- Sub Tenant (Level 2): 하위 조직 (예: 인사팀, 지사 B)
- 제약: Sub Tenant 밑에 또 다른 Tenant를 둘 수 없다.
2.2 리소스 소유권 (Resource Ownership)
- Root Tenant Only:
- Relying Party (Client App), IDP 설정 등 시스템의 핵심 리소스는 오직 Root Tenant만 생성하고 소유할 수 있다.
- 모든 정책(Policy) 결정 권한은 Root Tenant에게 있다.
- Sub Tenant:
- 독자적인 RP나 IDP 설정을 가질 수 없다.
- Root Tenant가 설정한 리소스를 공유하며, 단순히 사용자를 그룹핑하거나 조직 단위(Organizational Unit)로 관리하는 역할만 수행한다.
3. 데이터 모델 (Data Model)
3.1 사용자 관계 (User Membership)
사용자는 **단일 계정(User ID)으로 여러 Tenant에 동시에 소속(N:M 관계)**될 수 있다.
users테이블: 사용자의 고유 식별자 및 전역 속성(Email, Name, Phone)만 저장.tenants테이블: 테넌트 메타데이터 (id,parent_id,name등).parent_id가 NULL이면 Root Tenant이다.user_tenants테이블 (Membership):user_id와tenant_id를 매핑하며, 해당 테넌트 내에서의roles(권한) 정보를 저장한다.
3.2 ID 식별 및 매핑 (Identification)
- Internal Tenant ID: 시스템 내부적으로는 항상 UUID 기반의 고유 식별자를 사용한다.
- External Mapping: Descope, Ory Hydra 등 외부 IDP의 Tenant ID 형식이 다를 수 있으므로,
provider_mappings컬럼(또는 테이블)을 통해 외부 ID와 내부 UUID를 매핑한다.
4. 인증 및 인가 (Authentication & Authorization)
4.1 Active Tenant Context
사용자가 여러 Tenant에 속할 수 있으므로, 모든 API 요청은 **"현재 어떤 Tenant 문맥에서 작업 중인가"**를 명확히 해야 한다.
- Header:
X-Tenant-ID(필수) - Middleware 검증 로직:
- 요청 헤더에서
TargetTenantID를 추출한다. - User의 JWT Claims(또는 DB)를 확인하여, 사용자가
TargetTenantID에 소속되어 있는지 확인한다. - 해당 Tenant에서의 Role(예: Tenant Admin)이 요청한 작업을 수행할 권한이 있는지 검증한다.
- 요청 헤더에서
5. 보안 및 감사 (Security & Audit)
5.1 Audit Log 정책
X-Tenant-ID 헤더의 존재 여부와 관계없이, 모든 보안 이벤트는 반드시 기록되어야 한다.
- Tenant Context 존재 시: 해당
tenant_id와 함께 로그 저장. - Tenant Context 부재 시 (예: 로그인 직후, 프로필 수정, 내 테넌트 목록 조회):
tenant_id를NULL또는 예약어(system,personal)로 저장.
5.2 API 접근 제어 정책
- Tenant-Scoped API (예: RP 생성, 멤버 초대): 헤더 누락 시 400 Bad Request 거절.
- User/Global API (예: 내 정보 수정): 헤더 누락 허용 (Global Context).