forked from baron/baron-sso
문서 업데이트
This commit is contained in:
22
docs/AGENTS.md
Normal file
22
docs/AGENTS.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# AGENTS 가이드 (Baron SSO)
|
||||
|
||||
## 목적
|
||||
- Inbound Auth/Launcher와 관리(Admin) 기능을 하나의 백엔드에서 운영하되, 네임스페이스·도메인·권한으로 강하게 분리한다.
|
||||
- 사용자 플로우(가입/로그인)와 관리 플로우(Descope Management Key 사용)를 명확히 구분해 보안 사고면을 축소한다.
|
||||
|
||||
## 현재 원칙
|
||||
- **경계 분리**: `/admin/*` + admin 서브도메인에서만 관리 기능 노출. 일반 사용자 번들과 관리자 번들(또는 라우트)을 분리.
|
||||
- **관리 키 취급**: Descope Management Key는 서버 내부에서만 사용, 비동기 잡/관리 API에서 래핑. 모든 관리 액션을 감사 로그/알람/레이트리밋으로 보호.
|
||||
- **권한/가드**: role/permission 기반 접근 제어. 관리자 세션 TTL은 짧게, step-up MFA 고려.
|
||||
|
||||
## 인증 플로우 핵심
|
||||
- **최초 회원가입**: SMS 인증(Enchanted Link/OTP) 필수 → 인증 성공 후 계정 생성 및 초기 세션 발급.
|
||||
- **재로그인 분기 (앱 세션 보유 + 사용자 선택)**:
|
||||
- 앱 로그인 상태 + 사용자가 “앱 승인” 선택: 앱을 MFA/IDPW 대체 수단으로 사용(푸시/딥링크 승인) → 승인 시 웹 세션 발급.
|
||||
- 앱 세션이 없거나, 사용자가 이번 로그인에서 앱을 사용하지 않기로 선택: SMS 또는 이메일/비밀번호 경로로 진행.
|
||||
- **세션 TTL**: 앱 기반 세션 유지시간을 `APP_SESSION_TTL_MINUTES` 환경 변수로 관리(기본 예: 30분).
|
||||
|
||||
## 작업 시 체크리스트
|
||||
- 관리 기능 개발 시 admin 네임스페이스, 권한 체크, 감사 로깅, 레이트리밋을 기본 포함.
|
||||
- 인증/로그인 변경 시 “폴백은 사용자 선택일 때만” 규칙을 준수하고, UI에도 선택 흐름을 노출.
|
||||
- 새 설정/비밀값은 .env.sample에 반영하고 서버에서만 소비하게 설계한다.
|
||||
52
docs/Gemini.md
Normal file
52
docs/Gemini.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# Gemini Project Context - Baron SSO
|
||||
|
||||
## Project Identity
|
||||
- **Name**: Baron SSO
|
||||
- **Organization**: `kr.co.baroncs`
|
||||
- **Type**: User Authentication Hub & Unified Launcher
|
||||
- **Core Philosophy**: Secure, Seamless, White-labeled.
|
||||
|
||||
## Technical Preferences
|
||||
- **Language (Backend)**: Go (Golang) 1.25+
|
||||
- **Framework (Backend)**: Fiber (v2.25+)
|
||||
- **Database**:
|
||||
- PostgreSQL (Primary/Meta)
|
||||
- ClickHouse (Audit Logs - Local/Production)
|
||||
- **Language (Frontend)**: Dart (Flutter 3.32+)
|
||||
- **Platforms**: Web (PoC), iOS, Android.
|
||||
- **Auth Provider**: Descope
|
||||
- **Method**: Enchanted Link only (No Magic Link).
|
||||
- **Requirement**: Invisible to end-users (White-labeling).
|
||||
|
||||
## Core Scenarios
|
||||
1. **Same Browser SSO**: Access apps from Baron SSO launcher (logged in state).
|
||||
2. **Cross-Device Auth**: Approve PC login via Mobile Baron SSO app (Enchanted Link required).
|
||||
3. **Clean Login**: Email/SMS initial login. Future: OTP, MFA.
|
||||
|
||||
## Future Milestones
|
||||
- **Passkey Support**: Expanded seamless auth for Scenario 2 & 3.
|
||||
- **MFA Expansion**: OTP integration.
|
||||
|
||||
## Coding Standards
|
||||
- **Go**: Follow standard Go project layout (`cmd`, `internal`, `pkg`). Use Clean Architecture principles where appropriate. Handle errors explicitly.
|
||||
- **Flutter**: Use Riverpod for state management. Separate UI (Widgets) from Business Logic (Providers/Repositories).
|
||||
- **General**: Comments in Korean or English (User is Korean speaker).
|
||||
|
||||
## Workspace Structure
|
||||
Root: `/home/lectom/.gemini/antigravity/scratch/baron_sso`
|
||||
- `/backend`: Go Fiber Application
|
||||
- `/frontend`: Flutter Application
|
||||
- `/docs`: Documentation (PRD, API Specs)
|
||||
|
||||
## Current Status
|
||||
- **Planning Phase**: Completed PRD & Architecture.
|
||||
- **Next**: Backend Setup (Go/Fiber).
|
||||
|
||||
## Reference Analysis (Descope Sample App)
|
||||
- **Source**: `descope-sample-apps/flutter_sample_app_auth_func`
|
||||
- **Findings**:
|
||||
- **Setup**: Uses `.env` for `DESCOPE_PROJECT_ID`.
|
||||
- **Initialization**: `Descope.projectId = ...` and `Descope.sessionManager.loadSession()` in `main.dart`.
|
||||
- **Auth Check**: Checks `Descope.sessionManager.session?.refreshToken.isExpired`.
|
||||
- **Note**: Sample focuses on OAuth/OTP. Baron SSO requires **Enchanted Link**, which will use `Descope.auth.enchantedLink.signUpOrIn(...)` (inference based on SDK capability).
|
||||
- **Architecture**: Simple Provider/State management recommended (Riverpod chosen for Baron SSO).
|
||||
27
docs/idp_policy.md
Normal file
27
docs/idp_policy.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# IDP Abstraction & Perfect Wrapping Policy
|
||||
|
||||
## 1. 핵심 원칙 (Core Principles)
|
||||
|
||||
**"사용자와 클라이언트 개발자는 IDP가 무엇인지 알 수도 없고, 알아서도 안 된다."**
|
||||
|
||||
Baron SSO의 가장 중요한 아키텍처 원칙은 **IDP Agnostic(IDP 불가지론)**입니다. 현재 Descope를 사용하더라도, 내일 당장 Hydra, Authentik, Keycloak 또는 자체 구축 인증 서버로 변경하더라도 **Frontend, Client App, 그리고 최종 사용자에게는 단 1줄의 코드 변경이나 경험의 변화가 없어야 합니다.**
|
||||
|
||||
## 2. 세부 지침 (Guidelines)
|
||||
|
||||
### 2.1. Frontend & Client Side
|
||||
- **No Vendor SDK**: 프론트엔드 코드(User App, Admin Front)에서 `descope-sdk` 등 특정 벤더의 SDK를 직접 import하여 비즈니스 로직에 사용하는 것을 금지합니다.
|
||||
- **Unified Interface**: 모든 인증 요청은 Baron SSO Backend API (`/api/v1/auth/*`)를 통해서만 수행합니다.
|
||||
- **Response Format**: 클라이언트가 수신하는 토큰 및 사용자 정보는 Baron SSO가 정의한 표준 스키마(`BrokerUser`)여야 하며, IDP의 Raw Data가 노출되어서는 안 됩니다.
|
||||
|
||||
### 2.2. Backend Side
|
||||
- **Provider Pattern**: 모든 IDP 관련 로직은 `interface IDPProvider` 뒤에 숨겨야 합니다. 핸들러(Handler) 계층은 구체적인 구현체(DescopeService 등)를 알지 못해야 합니다.
|
||||
- **Error Mapping**: IDP에서 발생한 에러(예: `E062907`)는 반드시 Baron SSO의 표준 에러(예: `AUTH_PROVIDER_ERROR`)로 변환되어 클라이언트에 전달되어야 합니다.
|
||||
- **Configuration Isolation**: IDP 설정(Project ID, API Key)은 환경 변수와 팩토리 내부로 격리하며, 비즈니스 로직에 하드코딩하지 않습니다.
|
||||
|
||||
### 2.3. OIDC/OAuth2 Compliance
|
||||
- 외부 서비스(RP) 연동 시, Baron SSO 자체가 OIDC Provider로 동작해야 합니다.
|
||||
- RP는 `Issuer`를 Baron SSO의 URL로 설정하며, 원천 IDP의 URL을 바라보지 않습니다.
|
||||
|
||||
## 3. 마이그레이션 보장 (Migration Guarantee)
|
||||
이 정책의 최종 목표는 **"IDP 교체 비용을 0에 수렴하게 만드는 것"**입니다.
|
||||
IDP 변경 시 백엔드의 `IDPProvider` 구현체만 교체하면, 데이터 마이그레이션을 제외한 모든 서비스가 중단 없이 동작해야 합니다.
|
||||
55
docs/initial_PRD.md
Normal file
55
docs/initial_PRD.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# Baron SSO - Product Requirements Document (PRD)
|
||||
|
||||
## 1. 개요 (Overview)
|
||||
**Baron SSO**는 사용자 중심의 인증 허브이자 서비스 런처입니다. Descope를 IDP(Identity Provider)로 사용하여 강력한 보안(MFA)을 제공하면서도, 최종 사용자에게는 **Baron SSO**라는 브랜드 경험을 일관되게 제공하는 것을 목표로 합니다.
|
||||
|
||||
## 2. 목표 (Goals)
|
||||
- **Private IDP Hub**: 사용자가 자신의 계정 및 로그인 세션을 한곳에서 관리.
|
||||
- **Seamless Auth**: Descope의 Enchanted Link를 활용하여 비밀번호 없는 간편 로그인 제공.
|
||||
- **White-Labeling**: Descope의 UI를 노출하지 않고 자체 Flutter UI로 인증 흐름 완결.
|
||||
- **Audit & Security**: 모든 중요 인증 이벤트 및 접근 기록을 자체 Backend(Go Fiber)를 통해 ClickHouse에 Audit Log로 저장.
|
||||
- **Unified Launcher**: 인증 후 접근 가능한 서비스들을 한 화면에서 제공.
|
||||
|
||||
## 3. 기술 스택 (Tech Stack)
|
||||
- **Frontend**: Flutter (Web PoC 우선, 추후 iOS/Android)
|
||||
- **Backend (IDP)**: Descope (Auth Logic, User Management)
|
||||
- **Backend (Audit/API)**: Go (Fiber Framework)
|
||||
- **Database**: Postgres (Meta), ClickHouse (Audit Logs)
|
||||
- **Protocol**: OIDC/SAML (Service Integration), REST (Audit)
|
||||
|
||||
## 4. 주요 기능 (Key Features)
|
||||
|
||||
### 4.1 로그인 및 인증 (Authentication)
|
||||
- **로그인 방식 1 (Primary)**: 이메일 + 비밀번호 (Email/Password).
|
||||
- **로그인 방식 2 (Alternative)**: 전화번호 입력 -> Enchanted Link (SMS via Ncloud) -> 링크 클릭 -> 앱 로그인 완료 (Polling).
|
||||
- **SMS Provider**: Ncloud (Naver Cloud Platform) 연동.
|
||||
- **MFA (Multi-Factor Authentication)**: 필요 시 TOTP 또는 생체 인증 추가 (Descope Flow 설정). <- PoC Scope Out
|
||||
- **Descope Hiding**: Descope의 기본 화면 대신 Flutter로 구현된 커스텀 UI 사용.
|
||||
|
||||
### 4.2 대시보드 (Dashboard)
|
||||
- **내 계정 정보**: 프로필 확인/수정.
|
||||
- **활성 세션 리스트 (Active Sessions)**: 현재 로그인되어 있는 기기/브라우저 목록 확인 및 원격 로그아웃.
|
||||
|
||||
### 4.3 통합 런처 (Unified Launcher)
|
||||
- 로그인 승인 후 진입하는 메인 화면.
|
||||
- 접근 권한이 있는 하위 서비스 아이콘 나열 및 SSO 연결.
|
||||
|
||||
### 4.4 감사 로그 (Audit Backend)
|
||||
### 4.5 관리자 모드 (Admin Mode)
|
||||
- Descope API를 활용한 사용자 관리 (생성, 삭제, 상태 변경).
|
||||
- Descope 설정 및 흐름 관리 기능 노출 (필요 시).
|
||||
|
||||
## 5. 사용자 시나리오 (User Flow)
|
||||
1. 사용자가 Baron SSO 웹앱에 접속한다.
|
||||
4.1. **이메일 로그인**: 이메일과 비밀번호를 입력하고 로그인한다.
|
||||
4.2. **SMS 로그인**: 전화번호를 입력하고 '전송'을 누른다 -> 앱은 대기화면(Polling)으로 전환 -> 수신된 SMS 링크 클릭 -> 앱이 로그인 승인됨.
|
||||
4. 사용자가 앱푸시 혹은 이메일 수신함에서 Enchanted Link를 클릭한다.
|
||||
5. Baron SSO 웹앱이 로그인을 감지하고 메인 대시보드(런처)로 전환된다.
|
||||
6. 런처에서 '메일 서비스' 아이콘을 클릭하여 해당 서비스로 이동한다.
|
||||
|
||||
## 6. 마일스톤 (Milestones)
|
||||
1. **Phase 1 (Current)**: 기획 및 아키텍처 설계, 환경 구성.
|
||||
2. **Phase 2**: Go Fiber Backend (Audit) 기본 구현.
|
||||
3. **Phase 3**: Descope 설정 및 Flutter Web 기본 연동 (Enchanted Link).
|
||||
4. **Phase 4**: 대시보드 및 세션 관리 UI 구현.
|
||||
5. **Phase 5**: 관리자 모드 구현 및 통합 테스트 완료.
|
||||
64
docs/shadowing_policy.md
Normal file
64
docs/shadowing_policy.md
Normal file
@@ -0,0 +1,64 @@
|
||||
# Shadow Account Policy (Identity Sovereignty)
|
||||
|
||||
## 1. 개요 (Overview)
|
||||
Baron SSO는 외부 IDP(Descope 등)에 의존하지 않고, **식별자 주권(Identity Sovereignty)**을 갖기 위해 **Shadow Account (그림자 계정)** 모델을 채택합니다.
|
||||
외부 IDP는 단지 "인증 수단"일 뿐이며, 서비스 내부의 모든 비즈니스 로직, 로그, RP 연동은 Baron SSO가 발급한 고유 식별자(`Baron ID`)를 기준으로 수행됩니다.
|
||||
|
||||
## 2. 식별자 정책 (Identifier Policy)
|
||||
|
||||
### 2.1. Baron ID (Internal User ID)
|
||||
- **Format**: **UUID v7** (Time-ordered 128-bit)
|
||||
- **특징**: 생성 시간 순 정렬 가능, DB 인덱싱 효율 최적화, 외부 시스템 충돌 없음.
|
||||
- **용도**: `users` 테이블 PK, `audit_logs`의 Actor ID, RP에 전달되는 `sub` 값.
|
||||
- **원칙**: **불변(Immutable)**. 사용자가 이메일이나 연동 IDP를 변경해도 Baron ID는 변하지 않아야 합니다.
|
||||
|
||||
### 2.2. Audit Log ID
|
||||
- **Format**: **Snowflake** (64-bit Integer)
|
||||
- **용도**: 감사 로그의 Primary Key.
|
||||
- **이유**: 초당 대량으로 발생하는 로그 데이터의 적재 성능과 ClickHouse 압축 효율을 위해 정수형 ID 사용.
|
||||
|
||||
## 3. 데이터 모델 (Shadow Schema)
|
||||
|
||||
### 3.1. Users Table (Core)
|
||||
서비스가 바라보는 사용자의 실체입니다.
|
||||
```sql
|
||||
CREATE TABLE users (
|
||||
id UUID PRIMARY KEY, -- Baron ID (UUID v7)
|
||||
email VARCHAR(255), -- 검색 및 알림용 (Unique X, 여러 계정 가능성)
|
||||
name VARCHAR(100),
|
||||
status VARCHAR(20), -- 'active', 'blocked'
|
||||
created_at TIMESTAMPTZ,
|
||||
last_login_at TIMESTAMPTZ
|
||||
);
|
||||
```
|
||||
|
||||
### 3.2. Federated Identities Table (Mapping)
|
||||
외부 IDP 계정과 Baron 계정을 연결하는 매핑 테이블입니다. N:1 매핑이 가능합니다.
|
||||
```sql
|
||||
CREATE TABLE federated_identities (
|
||||
provider VARCHAR(50), -- 'descope', 'google', 'legacy_db'
|
||||
provider_sub VARCHAR(255), -- IDP의 원천 User ID
|
||||
user_id UUID REFERENCES users(id),
|
||||
created_at TIMESTAMPTZ,
|
||||
PRIMARY KEY (provider, provider_sub)
|
||||
);
|
||||
```
|
||||
|
||||
## 4. 동기화 및 로그인 흐름 (Sync Flow)
|
||||
|
||||
1. **인증 성공**: 백엔드가 IDP(Descope) 토큰을 검증하고 `Provider Sub`(예: `U12345`)를 획득.
|
||||
2. **조회 (Lookup)**: `federated_identities` 테이블에서 `(provider='descope', provider_sub='U12345')` 조회.
|
||||
3. **분기 처리**:
|
||||
- **Case A (기존 회원)**: 매핑된 `user_id` 획득. `users` 테이블의 정보(이메일, 이름)를 IDP 토큰 정보로 **업데이트(Sync)**.
|
||||
- **Case B (신규 회원)**: 새로운 `UUID v7` 생성 -> `users` Insert -> `federated_identities` Insert.
|
||||
4. **세션 발급**: Baron ID(`user_id`)를 Payload로 담은 Baron 자체 세션/토큰을 발급하여 클라이언트에 전달.
|
||||
|
||||
## 5. IDP 마이그레이션 전략 (Migration Strategy)
|
||||
|
||||
### 5.1. 식별자 유지
|
||||
IDP가 `Descope`에서 `Keycloak`으로 바뀌더라도, 백엔드는 새로운 IDP의 `sub`를 기존 사용자의 `Baron ID`와 매핑(`federated_identities` 추가)하기만 하면 됩니다. RP와 클라이언트는 아무런 변화를 감지하지 못합니다.
|
||||
|
||||
### 5.2. 비밀번호 처리 (Password Handling)
|
||||
- 해시된 비밀번호는 이관하지 않습니다 (불가능/비효율).
|
||||
- **Magic Link / Passwordless 우선**: 사용자는 비밀번호 입력 없이 계속 이용 가능.
|
||||
- **재설정 유도**: 비밀번호 사용 필수 시, "보안 정책 변경" 안내와 함께 리셋 링크 발송.
|
||||
@@ -1,61 +0,0 @@
|
||||
# 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 검증 로직**:
|
||||
1. 요청 헤더에서 `TargetTenantID`를 추출한다.
|
||||
2. User의 JWT Claims(또는 DB)를 확인하여, 사용자가 `TargetTenantID`에 소속되어 있는지 확인한다.
|
||||
3. 해당 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).
|
||||
Reference in New Issue
Block a user