IAM Operation 바운디드 컨텍스트
1. 컨텍스트 개요
IAM Operation Bounded Context는 Crm, Medical 플랫폼의 계정 인증(Authentication) 및 인가(Authorization)를 담당하는 핵심 도메인입니다.
비즈니스 목적: Crm, Medical 플랫폼의 사용자 계정 생명주기를 관리하고, 안전한 인증 메커니즘을 제공하여 의료진과 관리자가 플랫폼에 안전하게 접근할 수 있도록 보장
범위:
- 계정 생명주기 관리 (회원가입, 비밀번호 관리, 계정 삭제)
- 초대 기반 회원가입
- 비밀번호 재설정 (보안 코드 방식)
- 계정 잠금 및 보안 정책 적용
- 그룹 기반 권한 관리
포함하지 않는 것:
- 그룹 관리 (Group 담당)
- 세션 관리 (Auth 담당)
- 환자 상세 정보 조회 (User 담당)
2. 유비쿼터스 언어
| Term | Definition |
|---|---|
| 계정 (Account) | Crm, Medical 플랫폼에 접근할 수 있는 사용자 |
| 그룹 (Group) | 계정의 권한 범위를 결정하는 단위 (platform-admin, site-admin, site-member) |
| 사이트 (Site) | 계정이 소속된 의료 기관 또는 연구 단위 |
| 처방 권한 | 계정이 처방 관련 기능을 수행할 수 있는 권한 |
| 초대 (Invitation) | 신규 계정 생성을 위한 일회용 초대 코드 (UUID 기반) |
| 보안 코드 | 비밀번호 재설정을 위한 6자리 숫자 코드 (이메일 전송, 임시 저장) |
| 임시 액세스 토큰 | 보안 코드 검증 후 발급되는 30분 유효 토큰 (비밀번호 재설정 전용) |
| 비밀번호 해싱 | 클라이언트 1차 해싱 + SERVER_PEPPER 결합 후 bcrypt 재해싱 |
| 강제 초기화 | 관리자가 사용자의 비밀번호를 무작위 비밀번호로 재설정 (이메일 전송) |
| 마지막 관리자 | 사이트의 유일한 관리자 계정 (다른 계정 존재 시 삭제 불가) |
| 연구용 탭 | ClinicalResearch 타입 사이트에서만 접근 가능한 기능 |
| 관리자 API | /admin/* 경로의 API (platform-admin 그룹만 접근 가능) |
3. 컨텍스트 맵
3.1 관계 개요
용어 설명:
- 의존 (Depends on): 다른 Context의 데이터나 API를 호출하여 사용. 상대 Context가 없으면 동작 불가.
- 발행 (Publishes to): 이벤트를 다른 Context로 발행. 상대 Context의 처리 결과는 관심 없음.
- 구독 (Subscribes from): 다른 Context에서 발행한 이벤트를 받아서 처리.
IAM Operation Context
- 발행: Notification Context (비밀번호 초기화 이메일, 보안 코드 이메일 발송 요청)
- 발행: Audit Context (계정 생성, 로그인, 비밀번호 변경 등 감사 이벤트)
- 의존: Site Context (사이트 정보 조회, 사이트 삭제)
Notification Context
- 구독: IAM-Operation Context (이메일 발송 요청 이벤트 수신)
Audit Context
- 구독: IAM-Operatoin Context (인증/인가 관련 감사 이벤트 수신)
Site Context
- 발행: IAM-Operation Context (사이트 상태 변경 이벤트)
4. IAM Operation Context 상세
4.1 책임
- 계정 생명주기 관리 (생성, 수정, 삭제)
- 초대 기반 회원가입 처리
- 로그인 인증 및 토큰 발급
- 로그인 실패 추적 및 계정 잠금 관리
- 비밀번호 변경 및 검증
- 관리자에 의한 강제 비밀번호 초기화
- 보안 코드를 통한 비밀번호 재설정
- JWT 토큰 검증 및 갱신
- 그룹 기반 권한 제어
4.2 포함 Aggregate
Account
책임:
- 계정의 생명주기 전체 관리 (생성, 비밀번호 변경, 삭제)
- 계정 기본 정보 관리 (이메일, 이름, 전화번호)
- 그룹 및 사이트 소속 정보 관리
- 처방 권한 관리
주요 불변식:
- 동일한 이메일로 같은 그룹에 중복 가입 불가
- 비밀번호는 bcrypt 표준 포맷으로 저장
- 마지막 관리자는 다른 계정 존재 시 삭제 불가
LoginAttempt
책임:
- 로그인 시도 기록 관리
- 로그인 실패 횟수 추적
- 계정 잠금 상태 관리 (5회 실패 시 1분간 잠금)
주요 불변식:
- 로그인 성공 시 실패 횟수 자동 초기화
- 잠긴 계정은 시간 경과 후 자동 해제
Invitation
책임:
- 초대 생성 및 관리
- 초대 유효성 검증 (만료, 사용 여부)
- 초대 사용 완료 처리
주요 불변식:
- 초대는 1회만 사용 가능
- 초대 기반 계정 생성과 초대 상태 업데이트는 원자적 트랜잭션
SecurityCode
책임:
- 비밀번호 재설정용 보안 코드 생성
- 보안 코드 검증
- 임시 액세스 토큰 발급
주요 불변식:
- 보안 코드는 6자리 숫자이며 중복 불가
- 보안 코드는 캐시에 임시 저장 (데이터베이스 X)
- 검증 성공 후 30분 유효한 임시 토큰 발급
Token
책임:
- JWT 토큰 발급 (액세스, 리프레시, 임시)
- 토큰 검증 (시그니처, 만료, 도메인)
- 토큰 페이로드 구성 및 파싱
주요 불변식:
- 토큰은 계정 타입(at), 토큰 타입(type), 도메인(dom) 필수 포함
- 일반 사용자의 액세스 토큰만 도메인 검증 수행
- 리프레시 토큰은 데이터베이스에 저장
5. 주요 시나리오 흐름
5.1 일반 회원가입 흐름
사용자 → RegisterAccount 명령
↓
Account Aggregate (검증)
├─ 이메일/비밀번호 유효성 검증
├─ 그룹 중복 가입 여부 확인
└─ 비밀번호 해싱 (bcrypt)
↓
AccountCreated 이벤트 발행
↓
Audit Context (감사 로그 기록)
5.2 초대 기반 회원가입 흐름
사용자 → RegisterAccountViaInvitation 명령
↓
Invitation Aggregate (검증)
├─ 초대 UUID 존재 확인
├─ 만료 여부 확인
└─ 사용 여부 확인
↓
Account Aggregate (생성)
↓
[단일 트랜잭션]
├─ AccountCreatedViaInvitation 이벤트
└─ InvitationMarkedAsUsed 이벤트
↓
Audit Context (감사 로그 기록)
5.3 로그인 흐름
사용자 → Login 명령 (이메일 + 비밀번호)
↓
Account Aggregate (비밀번호 검증)
├─ bcrypt constant-time 비교
└─ 성공/실패 판단
↓
LoginAttempt Aggregate
├─ [성공] LoginAttemptCountReset 이벤트
│ ↓
│ Token Aggregate (토큰 발급)
│ ├─ AccessTokenIssued 이벤트
│ └─ RefreshTokenIssued 이벤트
│
└─ [실패] LoginAttemptRecorded 이벤트
├─ 실패 횟수 증가
└─ (5회 도달 시) AccountLocked 이벤트
5.4 보안 코드 비밀번호 재설정 흐름
[1단계: 보안 코드 요청]
사용자 → RequestPasswordResetSecurityCode 명령
↓
SecurityCode Aggregate
├─ 6자리 숫자 코드 생성
├─ 중복 검증 (재생성)
└─ SecurityCodeStoredInCache 이벤트
↓
Notification Context (이메일 전송)
[2단계: 보안 코드 검증]
사용자 → VerifySecurityCode 명령
↓
SecurityCode Aggregate (검증)
├─ 코드-이메일 일치 확인
└─ 만료 여부 확인
↓
SecurityCodeValidated 이벤트
↓
Token Aggregate
└─ TemporaryAccessTokenIssued 이벤트 (30분 유효)
[3단계: 비밀번호 재설정]
사용자 → ResetPasswordWithTemporaryToken 명령 + 임시 토큰
↓
Token Aggregate (토큰 검증)
↓
Account Aggregate
├─ 기존 비밀번호와 중복 검증
└─ 비밀번호 업데이트
↓
PasswordResetWithTemporaryToken 이벤트
5.5 강제 비밀번호 초기화 흐름
관리자 → ForceResetPassword 명령
↓
Account Aggregate
├─ 무작위 비밀번호 생성
└─ 비밀번호 업데이트
↓
[단일 트랜잭션]
├─ PasswordForciblyReset 이벤트
└─ Notification Context (이메일 전송)
├─ [성공] PasswordResetEmailSent 이벤트
└─ [실패] 트랜잭션 롤백 (비밀번호 변경도 취소)
6. 보안 고려사항
6.1 비밀번호 보안
- 이중 해싱: 클라이언트 1차 해싱 + 서버 SERVER_PEPPER 결합 후 bcrypt 재해싱
- Salt: bcrypt 자동 salt 생성 및 포함
- Constant-time 비교: 타이밍 공격 방지
6.2 토큰 보안
- 짧은 유효기간: 액세스 토큰은 짧은 TTL 설정
- 리프레시 토큰 저장: 데이터베이스에 저장하여 무효화 가능
- 도메인 검증: 일반 사용자의 토큰은 도메인 정보 검증
6.3 계정 보호
- 로그인 실패 제한: 5회 연속 실패 시 1분간 계정 잠금
- 보안 코드 유효기간: 캐시에 TTL 설정하여 자동 만료
- 마지막 관리자 보호: 사이트의 유일한 관리자 삭제 방지
6.4 감사 추적
- 로그인 이력: 모든 로그인 시도 기록 (성공/실패)
- 비밀번호 변경 이력: 변경 주체 및 유형 기록
- 이메일 전송 이력: 보안 관련 이메일 발송 기록
변경 이력
| 버전 | 날짜 | 작성자 | 변경 내용 |
|---|---|---|---|
| 0.57.0 | 2025-12-15 | dalia@weltcorp.com | Requirements 기반 Bounded Context 작성 |