1
0
forked from baron/baron-sso

Resolve merge conflicts with main

This commit is contained in:
2026-01-29 16:45:40 +09:00
69 changed files with 6049 additions and 1379 deletions

89
docs/auth-flow.md Normal file
View File

@@ -0,0 +1,89 @@
# 인증/로그인 플로우 정리 (Backend IDP 추상화 기준)
이 문서는 **Backend IDP 추상화(IdentityProvider)**를 기준으로, 현재 지원하는 로그인 방식과 UserFront 연동 API, 그리고 **Kratos 세션 공유 방식**을 정리합니다.
> 목적: ID/Password 방식부터 시작해, 현재 지원 중인 로그인 플로우를 **IDP 추상화를 해치지 않는 범위**에서 일관되게 구현하고, Front/Backend/Oathkeeper 간 세션 전달 방식을 명확히 한다.
---
## 1) 지원 로그인 방식 요약
| 방식 | Backend 엔드포인트 | 세션 토큰 반환 | 비고 |
|---|---|---|---|
| ID/Password | `POST /api/v1/auth/password/login` | `sessionJwt` | IDP 추상화 사용 (Ory/Descope) |
| Enchanted Link (Email/SMS) | `POST /api/v1/auth/enchanted-link/init``POST /api/v1/auth/enchanted-link/poll` | `sessionJwt` | 링크 클릭 시 `POST /api/v1/auth/magic-link/verify` 호출 |
| Magic Link Verify | `POST /api/v1/auth/magic-link/verify` | `token` | Polling 세션 갱신용 |
| SMS 코드 | `POST /api/v1/auth/sms``POST /api/v1/auth/verify-sms` | `token` | 현재는 내부 토큰(placeholder). Kratos 세션 교환 필요 |
| QR 로그인 | `POST /api/v1/auth/qr/init``POST /api/v1/auth/qr/poll` | `sessionJwt` | 모바일 승인: `POST /api/v1/auth/qr/approve` |
---
## 2) UserFront 연동 API 매핑
### 2.1 ID/Password 로그인
1. `POST /api/v1/auth/password/login`
2. 응답의 `sessionJwt` 사용
### 2.2 Enchanted Link (Email/SMS)
1. `POST /api/v1/auth/enchanted-link/init``pendingRef` 수신
2. `POST /api/v1/auth/enchanted-link/poll`로 폴링
3. 사용자가 링크 클릭하면 UserFront가 `POST /api/v1/auth/magic-link/verify` 호출
4. Polling 응답에서 `sessionJwt` 수신
### 2.3 QR 로그인
1. `POST /api/v1/auth/qr/init``qrCode`, `pendingRef` 수신
2. 웹은 `POST /api/v1/auth/qr/poll`로 폴링
3. 모바일 앱은 `POST /api/v1/auth/qr/approve`로 승인 (모바일 세션 토큰은 승인 검증용)
4. Polling 응답에서 `sessionJwt` 수신
### 2.4 SMS 코드 로그인
1. `POST /api/v1/auth/sms`로 코드 발송
2. `POST /api/v1/auth/verify-sms`로 코드 검증
3. 현재는 내부 토큰 반환 (IDP 세션 교환은 TODO)
---
## 3) Kratos 세션 생성/공유 방식
### 3.1 생성 (ID/Password 기준)
- Backend가 IDP 추상화(`IdentityProvider.SignIn`)를 호출해 `sessionJwt`를 발급
- **Ory(Kratos)**의 경우:
- Kratos Login API를 통해 `session_token`을 반환
- 이 값이 `sessionJwt`로 응답됨
### 3.2 공유 (Backend → UserFront / Oathkeeper)
현재 공유 방식은 **두 가지 선택지**가 있습니다.
**A) Backend가 쿠키로 전달 (권장 방향)**
- `sessionJwt`가 Kratos `session_token`인 경우 `ory_kratos_session` 쿠키로 `Set-Cookie`
- Oathkeeper `cookie_session` authenticator가 Kratos `/sessions/whoami`로 검증 가능
**B) UserFront가 토큰을 보관/전달 (현재 동작)**
- `sessionJwt`를 로컬에 저장 후 Backend 호출 시 `Authorization: Bearer <token>`로 전달
- Oathkeeper 경유 경로에서는 쿠키가 필요하므로, 별도 토큰 교환 또는 Oathkeeper 인증기 추가가 필요
> 현재 구현은 **B 방식에 가깝고**, Oathkeeper 통과를 위한 쿠키 전달은 추가 구현이 필요합니다.
---
## 4) IDP 추상화 관점에서의 구현 상태
- **ID/Password 로그인**: IDP 추상화 사용 (Ory/Descope) — 정상
- **Enchanted/Magic Link**: 현재는 Descope 기반 로직이 포함됨. Ory 전환 시 Kratos `code/link` 플로우로 교체 필요
- **SMS 코드**: 내부 토큰(placeholder). Kratos 세션 교환 로직 추가 필요
- **QR 로그인**: 모바일 세션 토큰은 승인 검증용으로만 사용하고, 백엔드에서 웹 전용 세션을 새로 발급
---
## 5) UserFront 주의사항
- `sessionJwt`**JWT 형식이 아닐 수 있음** (Kratos session token은 opaque 가능)
- 현재 UserFront는 Descope SDK 기반 세션 처리 로직이 포함되어 있어, Ory 사용 시 이 부분은 분리/대체가 필요함
---
## 6) 다음 액션 제안
1. **Kratos 세션 쿠키 전달 방식(A) 구현**
2. Enchanted/Magic Link의 Ory 대응(로그인 코드/링크 방식) 설계
3. SMS 코드/QR 플로우의 Kratos 세션 교환 정책 확정

View File

@@ -0,0 +1,34 @@
# Ory Kratos 인증 엔진 전환 작업 보고서
## 1. 개요
기존 Descope SaaS 기반 인증 시스템을 자가 호스팅(Self-hosted) IDP인 **Ory Kratos**로 전환하고, 이를 백엔드(Go Fiber)와 연동하는 작업을 수행하였습니다.
## 2. 주요 작업 내용
### 2.1 인프라 및 SDK 설정
* **SDK 설치**: Ory Kratos Go SDK (`github.com/ory/kratos-client-go`)를 백엔드 프로젝트에 추가.
* **클라이언트 초기화**: `AuthHandler` 내부에 Kratos Public API 통신을 위한 API Client 주입 및 환경 변수 연동.
### 2.2 인증 Flow 핸들러 구현 (`auth_handler.go`)
Ory Kratos의 API-first 방식(Native Flow)에 맞춘 신규 핸들러 구현:
* **InitializeLoginFlow**: 로그인 프로세스 시작을 위한 `flow_id` 발급 API.
* **InitializeRegistrationFlow**: 회원가입 프로세스 시작을 위한 `flow_id` 발급 API.
* **LoginSubmit**: 사용자의 ID/PW를 Kratos에 제출하고 성공 시 세션 쿠키를 클라이언트에 전달.
* **RegistrationSubmit**: 커스텀 Traits(사용자 정보)와 비밀번호를 Kratos에 전달하여 계정 생성.
### 2.3 라우팅 설정 (`main.go`)
신규 인증 엔진을 위한 전용 엔드포인트 그룹 등록:
* `GET /api/v1/auth/ory/login/initialize`
* `POST /api/v1/auth/ory/login/submit`
* `GET /api/v1/auth/ory/registration/initialize`
* `POST /api/v1/auth/ory/registration/submit`
### 2.4 보안 및 감사 (Security & Audit)
* **세션 관리**: Kratos에서 발급한 `Set-Cookie` 헤더를 추출하여 클라이언트에 투명하게 전달(Pass-through).
* **감사 로그**: 로그인 시도 및 성공 시 시각, IP, 대상 아이디 등을 ClickHouse 감사 로그 시스템에 기록.
* **타입 오류 해결**: Kratos SDK의 구조체 타입 미스매치 이슈 해결(`result.Session` nil 비교 로직 수정).
## 3. 향후 과제 (Next Steps)
1. **UI 연동**: `userfront` (Flutter)의 API 엔드포인트를 기존 Descope에서 신규 Ory 경로로 전환.
2. **계정 복구**: 비밀번호 찾기(Recovery) 및 이메일 확인(Verification) Flow 추가 연동.
3. **관리자 기능**: `adminfront`에서 Kratos Identities를 직접 조회/삭제하는 관리 API 연결.

27
docs/kratos-todo-list.md Normal file
View File

@@ -0,0 +1,27 @@
# Kratos 기반 SSO 추가 기능 구현 로드맵
Ory Kratos의 표준 기능을 바탕으로 우리 프로젝트에 추가해야 할 핵심 기능 목록입니다.
## 1. 인증 수단 고도화
- [ ] **소셜 로그인 연동**: Google, GitHub, Apple 등 주요 OIDC 제공자 연결.
- [ ] **Passkeys (WebAuthn)**: 생체 인증을 통한 Passwordless 로그인 구현.
- [ ] **MFA (Multi-Factor Authentication)**: TOTP(Authenticator 앱), Lookup Secret(복구 코드) 지원.
## 2. 사용자 셀프 서비스 (Self-Service)
- [ ] **계정 복구 Flow**: 비밀번호 분실 시 이메일/SMS 링크를 통한 재설정 기능.
- [ ] **계정 확인 (Verification)**: 가입 시 이메일/전화번호 점유 인증 절차.
- [ ] **프로필 및 설정 화면**: 사용자가 직접 자신의 정보(Traits)와 비밀번호를 수정하는 화면.
## 3. 세션 보안 관리
- [ ] **기기별 세션 관리**: 현재 로그인된 모든 브라우저/기기 목록 조회 및 특정 세션 강제 종료 기능.
- [ ] **보안 로그 제공**: 사용자 본인의 최근 로그인 기록 및 보안 이벤트 확인 기능.
## 4. 관리자 기능 (Admin Operations)
- [ ] **커스텀 아이덴티티 스키마**: 테넌트 요구사항에 맞춘 사용자 필드(부서, 직번 등) 동적 정의.
- [ ] **사용자 일괄 마이그레이션**: 외부 데이터 대량 Import/Export API 및 도구.
- [ ] **계정 상태 강제 제어**: 관리자에 의한 계정 잠금(Ban) 및 활성화 처리.
## 5. 시스템 연동 및 브랜딩
- [ ] **메시지 템플릿 관리**: 이메일/SMS 발송 템플릿의 커스텀 HTML 에디터 및 미리보기.
- [ ] **Webhook 이벤트 연동**: 가입/로그인 등 주요 이벤트 발생 시 외부 시스템으로 실시간 데이터 전송.
- [ ] **멀티테넌시 브랜딩**: 접속 도메인이나 테넌트에 따른 로그인 화면 로고/컬러 동적 적용.

84
docs/ory-stack-guide.md Normal file
View File

@@ -0,0 +1,84 @@
# Ory Stack 상세 가이드 (Baron SSO)
이 문서는 Baron SSO의 핵심 엔진인 Ory Stack의 구성 요소와 전체적인 인증/인가 플로우를 설명합니다.
## 1. 구성 요소별 상세 역할
| 구성 요소 | 별칭 | 주요 역할 | 핵심 기능 |
| :------------- | :------------ | :--------------- | :-------------------------------------------- |
| **Kratos** | Identity | **사용자 관리** | 회원가입, 로그인, MFA, 프로필 수정, 계정 복구 |
| | | | |
| **Hydra** | OAuth2/OIDC | **연동 및 토큰** | Access/ID 토큰 발급, 외부 서비스 SSO 연동 |
| **Keto** | Authorization | **권한 제어** | RBAC, ACL, "누가 무엇을 할 수 있는가" 판별 |
| **Oathkeeper** | Proxy/Gateway | **접근 통제** | 요청 검증, 세션 확인, 헤더 변환, API 보호 |
---
## 2. 시스템 플로우 (System Flow)
사용자가 보호된 백엔드 리소스에 접근할 때의 일반적인 흐름입니다.
### [인증 및 접근 흐름]
1. **Request**: 사용자가 API 요청을 보냄 (예: `GET /api/data`).
2. **Intercept (Oathkeeper)**: Oathkeeper가 요청을 가로챔.
3. **Authenticate (Kratos)**: Oathkeeper가 Kratos에게 사용자의 세션 쿠키가 유효한지 확인.
4. **Authorize (Keto)**: Oathkeeper가 Keto에게 해당 사용자가 `/api/data`를 볼 권한이 있는지 확인.
5. **Transform**: 모든 검증이 끝나면 Oathkeeper가 사용자 정보를 헤더(예: `X-User-ID`)에 담아 백엔드로 전달.
6. **Response**: 백엔드가 로직을 수행하고 결과를 반환.
### [SSO 연동 흐름 (OIDC)]
1. **Discovery**: 외부 서비스(App A)가 로그인 필요 시 Hydra로 인증 요청을 보냄.
2. **Login Challenge**: Hydra가 로그인 UI(`userfront`)로 리다이렉트하며 챌린지를 보냄.
3. **Auth (Kratos)**: 사용자가 `userfront`에서 로그인(Kratos 사용).
4. **Accept**: `userfront`가 로그인 성공 시 Hydra에게 챌린지 수락을 알림.
5. **Token Issuance**: Hydra가 App A에게 Auth Code를 주고, App A는 이를 Access/ID Token으로 교환.
---
## 3. 아키텍처 다이어그램
```mermaid
graph TD
User((사용자))
subgraph "Edge / Gateway"
OK[Ory Oathkeeper]
end
subgraph "Identity & Access Layer"
KR[Ory Kratos]
HY[Ory Hydra]
KE[Ory Keto]
end
subgraph "Application Layer"
BE[Backend API]
AF[Admin Front]
UF[User Front]
end
User -->|API Request| OK
User -->|Login/Register| UF
UF --> KR
OK -->|1. 세션 확인| KR
OK -->|2. 권한 확인| KE
OK -->|3. 요청 전달| BE
AF -->|관리 작업| BE
BE -->|Admin API 호출| KR & HY & KE
HY -->|SSO 토큰 발급| User
```
---
## 4. 요약
- **Kratos**는 사용자의 정보를 알고 있습니다.
- **Keto**는 사용자의 권한을 알고 있습니다.
- **Hydra**는 사용자를 외부 서비스에 증명합니다.
- **Oathkeeper**는 위 서비스들을 이용해 입구를 지킵니다.

View File

@@ -95,3 +95,4 @@ docker run --rm --network baron_net curlimages/curl:8.10.1 -fsS http://kratos:44
- `compose.ory.yaml`
- `docker/ory/kratos/kratos.yml`
- `.env.sample`
- `docs/auth-flow.md`