Auth 도메인 이벤트 스토밍
개요
본 문서는 Auth(Authentication) 도메인의 이벤트 스토밍 워크샵 결과를 정리한 것입니다. 도메인 전문가, 개발자, 그리고 이해관계자들이 참여하여 도출된 도메인 이벤트, 명령, 액터, 정책 등을 포함합니다. 사용자 인증, 세션 관리, 앱 보안, OAuth 통합에 중점을 둡니다.
바운디드 컨텍스트 참조
- Auth 도메인은 사용자 식별 및 접근 제어를 담당하며, Access Code, Terms, Consent, User, IAM 등 여러 다른 도메인과 상호작용합니다.
- Access Code: 회원가입 시 Access Code 검증을 위해 협력합니다.
- Terms: 회원가입 및 서비스 이용 시 필요한 약관 정보를 조회하고, 사용자 동의 정보를 기록하도록 Terms 도메인에 요청할 수 있습니다.
- Consent: 회원가입 및 서비스 이용 시 필요한 동의 상태를 조회하고, 사용자 동의 결과를 Consent 도메인에 기록하도록 요청하며, 발급된 토큰에 동의 정보를 포함합니다.
- User: 사용자 계정 정보(이메일, 상태 등)를 참조하고, 회원가입 시 User 도메인에 사용자 생성을 요청합니다.
- IAM: 역할 및 권한 정보를 참조하여 토큰에 포함시키거나 접근 제어에 활용합니다.
- 상세한 컨텍스트 매핑은
bounded-context.md문서를 참조하세요.
도메인 이벤트
도메인에서 발생하는 중요한 변화나 사실을 나타내는 이벤트들입니다.
백엔드 이벤트
| 이벤트 | 설명 | 트리거 |
|---|---|---|
| DeviceRegistered | 새 디바이스가 등록되었음 | RegisterDevice |
| AppTokenIssued | 앱 토큰이 발급되었음 | IssueAppToken |
| AppIntegrityVerified | 앱 무결성 검증이 성공했음 | VerifyAppIntegrity |
| AppIntegrityViolated | 앱 무결성 검증이 실패했음 | 변조된 앱 감지 |
| DeviceBlacklisted | 디바이스가 블랙리스트에 추가되었음 | BlacklistDevice |
| ChallengeIssued | 보안 챌린지가 생성되었음 | GenerateChallenge |
| ChallengeVerified | 보안 챌린지 검증이 성공했음 | VerifyChallenge |
| AccessCodeValidated | 서버가 사용자가 제출한 Access Code의 유효성을 확인했음 (Access Code 도메인 이벤트 수신 또는 직접 검증 결과) | ValidateAccessCode |
| AccessCodeValidationFailed | Access Code 인증에 실패했음 | ValidateAccessCode |
| EmailVerificationCodeSent | 서버가 이메일로 인증 코드를 발송했음 | RequestEmailVerification |
| EmailVerificationCodeSentInUserLanguage | 서버가 사용자 선호 언어로 이메일 인증 코드를 발송했음 | RequestEmailVerificationWithLanguage |
| EmailVerificationCodeExpired | 이메일 인증코드 확인 만료시간(5분)이 지남 | 시간 만료 |
| EmailVerificationCodeValidated | 서버가 제출한 인증코드가 유효한지 확인했음 | ValidateEmailVerificationCode |
| EmailVerificationCompleted | 서버가 이메일 인증코드를 승인했음 | 인증 코드 검증 성공 |
| UserRegistrationCompleted | 사용자 회원가입이 완료되었음 (User 도메인 이벤트 수신 또는 직접 처리 결과) | RegisterUser |
| GuestOnboarded | 게스트 계정이 약관 동의만으로 생성되었음 | OnboardGuest |
| GuestOnboardingFailed | 게스트 온보딩 중 정책 위반이나 검증 실패가 발생했음 | OnboardGuest |
| StepUpLinkSessionCreated | 게스트 Step-up 인증 세션이 생성되었음 | InitializeStepUp |
| StepUpLinkSessionExpired | Step-up 인증 세션이 만료되었음 | TimeMachine 트리거 |
| StepUpLinkSessionCancelled | Step-up 인증 세션이 취소되었음 | CancelStepUp |
| StepUpCompleted | 게스트 계정이 정규 사용자로 승격되었음 | CompleteStepUp |
| IdentityLevelChanged | 사용자 identityLevel이 변경되었음 | CompleteStepUp / 관리자 조치 |
| StepUpRateLimited | Step-up 인증 실패가 정책 한도를 초과했음 | ValidateStepUpAttempt |
| EmailNotFound | 존재하지 않은 이메일로 로그인 요청을 받음 | LoginUser |
| PasswordIncorrect | 잘못된 비밀번호로 로그인 요청을 받음 | LoginUser |
| LoginFailed | 로그인 시도가 실패했음 | 잘못된 인증 정보 |
| DeviceTemporarilyBlocked | 동일한 Device Id로 연속 로그인 실패가 발생 | 연속 로그인 실패 |
| MFAVerified | 다중 인증이 검증되었음 | VerifyMFA |
| PreviousTokensInvalidated | 다른 디바이스 로그인으로 이전 토큰 무효화 | InvalidatePreviousTokens |
| UserLoggedIn | 사용자가 성공적으로 로그인했음 | LoginUser 성공 |
| SessionCreated | 새로운 세션이 생성되었음 | 로그인 성공 |
| TokensIssued | Access Token 발급(consents 클레임 포함) | 로그인 성공 |
| TokenRefreshed | 토큰이 갱신되었음 | RefreshToken |
| UserLoggedOut | 사용자가 로그아웃했음 | LogoutUser |
| SessionExpired | 세션이 만료되었음 | 시간 초과 |
| PasswordResetWithInvalidCode | 비밀번호 재설정 인증코드가 유효하지 않음 | 인증 코드 검증 |
| PasswordResetCompleted | 비밀번호 재설정이 완료되었음 | ResetPassword |
| PasswordChanged | 사용자 비밀번호가 변경되었음 | ChangePassword |
| TokenRevoked | 토큰이 폐기되었음 | RevokeToken |
| OAuthCallbackReceived | OAuth 콜백이 수신되었음 | ProcessOAuthLogin |
| OAuthAccountLinked | OAuth 계정이 연동되었음 | LinkOAuthAccount |
| OAuthAccountUnlinked | OAuth 계정 연동이 해제되었음 | UnlinkOAuthAccount |
| SecurityViolationDetected | 보안 위반이 감지되었음 | 시스템 감지 |
| AccountLocked | 계정이 잠겼음 | LockAccount |
| AccountUnlocked | 계정 잠금이 해제되었음 | UnlockAccount |
| GesundheitsIDLinked | GesundheitsID가 계정에 연동되었음 | LinkGesundheitsID |
| GesundheitsIDUnlinked | GesundheitsID 연동이 해제되었음 | UnlinkGesundheitsID |
| GesundheitsIDLoginSucceeded | GesundheitsID를 통한 로그인이 성공했음 | LoginWithGesundheitsID |
| GesundheitsIDLoginFailed | GesundheitsID를 통한 로그인이 실패했음 | 인증 실패 |
| OperationUserRegistered | 내부 운영자 사용자가 등록되었음 | RegisterOperationUser |
| OperationUserDeleted | 내부 운영자 사용자가 삭제되었음 | DeleteOperationUser |
| OperationUserLoginFailed | 내부 운영자 로그인 시도가 실패했음 | LoginOperationUser |
| OperationUserLoggedIn | 내부 운영자가 성공적으로 로그인했음 | LoginOperationUser 성공 |
| OperationUserLoggedOut | 내부 운영자가 로그아웃했음 | LogoutOperationUser |
| OperationTokensIssued | 내부 운영자용 토큰이 발급되었음 | 운영자 로그인 성공 |
| OperationTokenRefreshed | 내부 운영자용 토큰이 갱신되었음 | RefreshOperationToken |
| OperationEmailVerificationCodeSent | 내부 운영자 이메일로 인증 코드가 발송되었음 | RequestOperationEmailVerification |
| OperationEmailVerified | 내부 운영자 이메일 인증이 완료되었음 | ValidateOperationEmailVerificationCode |
| UserTypeChanged | 사용자 유형이 변경되었음 (환자/내부 운영자 간 전환) | ChangeUserType |
프론트엔드 이벤트
| 이벤트 | 설명 | 트리거 |
|---|---|---|
| AccessCodeSubmitted | 사용자가 16자리 Access Code를 서버에게 제출했음 | 회원가입 시도 |
| DuplicateAccessCodeSubmitted | 사용자가 이미 사용 중인 Access Code를 제출했음 | 회원가입 시도 |
| InvalidAccessCodeSubmitted | 사용자가 정식으로 발급되지 않은 Access Code를 제출했음 | 회원가입 시도 |
| EmailSubmitted | 사용자가 본인 인증을 위해 이메일을 제출했음 | 이메일 제출 |
| InvalidEmailFormatSubmitted | 사용자가 잘못된 형식의 이메일을 제출했음 | 이메일 제출 |
| EmailValidated | 제출된 이메일이 유효한지 확인했음 | 이메일 검증 |
| EmailVerificationCodeSubmitted | 사용자가 이메일 인증코드를 서버로 제출했음 | 인증 코드 입력 |
| EmailVerificationCodeResent | 사용자가 이메일 인증코드를 다시 보내도록 요청했음 | 재전송 요청 |
| PasswordSubmitted | 사용자가 적합한 비밀번호를 앱에게 제출했음 | 비밀번호 입력 |
| PinCodeSubmitted | 사용자가 간편 인증을 위하여 PIN 코드를 앱에게 제출했음 (로컬 처리) | PIN 코드 입력 |
| BiometricAuthEnabled | 사용자가 생체 인증 기능을 사용할 것임을 제출했음 (로컬 처리) | 생체 인증 설정 |
| UserRegistrationRequested | 앱이 서버에게 회원가입을 요청했음 (필수 동의 정보 포함) | 모든 필수 정보 입력 완료 |
| LoginRequested | 사용자가 이메일, 비밀번호로 로그인을 요청했음 | 로그인 시도 |
| AutoLoginRequested | 사용자가 자동 로그인을 시도했음 (로컬 저장 정보 사용) | 앱 실행 |
| KeepLoginStateRequested | 사용자가 '로그인 상태 유지하기' 옵션을 선택했음 | 로그인 옵션 선택 |
| AppBackgrounded | 앱이 백그라운드로 전환되었음 | 사용자 앱 전환 |
| AppForegrounded | 앱이 포그라운드로 복귀했음 | 사용자 앱 복귀 |
| ShortSessionRestored | 30분 이내 백그라운드에서 복귀로 세션 복원 | 앱 포그라운드 전환 |
| SimplifiedAuthRequested | 30분~4시간 이내 백그라운드에서 복귀로 간편인증 요청 | 앱 포그라운드 전환 |
| PasswordResetRequested | 비밀번호 재설정이 요청되었음 | 재설정 요청 |
| OAuthLoginStarted | OAuth 로그인이 시작되었음 | StartOAuthLogin |
| RequestDeviceRegistration | 디바이스 등록을 요청함 | 앱 설치 및 최초 실행 |
| RequestAppToken | 앱 토큰을 요청함 | 디바이스 등록 성공 |
| SubmitChallengeResponse | 보안 챌린지에 대한 응답을 제출함 | 챌린지 응답 요청 |
| StoreAppToken | 앱 토큰을 저장함 | 토큰 발급 완료 |
| AttemptLogin | 로그인을 시도함 | 사용자 로그인 요청 |
| LogoutUser | 로그아웃을 요청함 | 사용자 로그아웃 요청 |
| SubmitPasswordResetRequest | 비밀번호 재설정 요청을 제출함 | 비밀번호 재설정 요청 |
| SubmitNewPassword | 새 비밀번호를 제출함 | 새 비밀번호 설정 |
| GesundheitsIDLinkRequested | GesundheitsID 연동을 요청함 | 사용자 연동 요청 |
| GesundheitsIDUnlinkRequested | GesundheitsID 연동 해제를 요청함 | 사용자 연동 해제 요청 |
| GesundheitsIDLoginRequested | GesundheitsID로 로그인을 요청함 | GesundheitsID 로그인 시도 |
| GesundheitsIDSettingsDisplayed | GesundheitsID 설정 화면이 표시됨 | 설정 메뉴 접근 |
정책(Policies)
시스템의 자동화된 비즈니스 규칙입니다.
앱 보안 정책
백엔드 정책
- 앱 무결성 검증 필수화
- 시간 기반 챌린지-응답 메커니즘
- 수상한 디바이스 자동 블랙리스트
- 디바이스 ID 해싱 및 솔트 적용
- 디바이스별 권한 제한
프론트엔드 정책
- 루팅/탈옥 디바이스 감지
- 안전한 키 저장소 사용
- 앱 내 민감 정보 암호화
- 디바이스 ID 생성 및 SHA-256 해싱 적용
- 백그라운드 스크린샷 보호
인증 정책
백엔드 정책
- 연속된 로그인 실패 시 계정 잠금
- 장기 미사용 계정 비활성화
- 강력한 비밀번호 정책 적용
- 세션 타임아웃 관리
프론트엔드 정책
- 로그인 UI에서 보안 요구사항 표시
- 비밀번호 강도 미터 제공
- 로그인 실패 시 적절한 사용자 피드백 제공
토큰 정책
백엔드 정책
- 토큰 만료 시간 설정
- 토큰 갱신 제한
- 동시 세션 제한
- 토큰 폐기 정책
프론트엔드 정책
- 토큰 로컬 보안 저장
- 토큰 만료 시 자동 갱신 처리
- 인증 실패 시 토큰 저장소 클리어
토큰 관리 정책
백엔드 정책
- JWT 토큰 타임아웃 설정 관리
- 토큰 블랙리스트 관리 및 TTL 설정
- 사용자별 마지막 로그인 디바이스 식별 및 관리
- 단일 사용자는 한 번에 하나의 디바이스에서만 활성 토큰 보유 가능
- 새 디바이스 로그인 시 이전 디바이스 토큰 자동 블랙리스트 추가
- 로그아웃 시 토큰 즉시 블랙리스트 추가 및 무효화
- 블랙리스트된 토큰은 모든 API 요청에서 거부
프론트엔드 정책
- 앱 백그라운드 전환 후 30분 이내 복귀 시 기존 토큰으로 자동 접근
- 앱 백그라운드 전환 후 30분~4시간 내 복귀 시 간편인증 후 토큰 사용
- 4시간 초과 시 토큰 삭제 및 전체 재인증 요구
- '로그인 상태 유지하기' 옵션 사용 시 장기 토큰 보관 허용
- 자동 로그인을 위한 디바이스 내 안전한 토큰 저장
보안 정책
백엔드 정책
- MFA 필수 조건 설정
- IP 기반 접근 제한
- 비정상 행동 탐지
- 보안 이벤트 로깅
프론트엔드 정책
- 민감한 인증 정보의 안전한 저장
- 화면 잠금 시 앱 내 민감 정보 난독화
- 디바이스 무결성 검증 협조
사용자 유형 분리 정책
백엔드 정책
- 사용자 유형(환자/내부 운영자)에 따라 데이터 저장 스키마 분리
- 환자 사용자 데이터는
private스키마에 저장 - 내부 운영자 데이터는
operation스키마에 저장 - 내부 운영자 등록은 SYSTEM_ADMIN 권한 필요
- 내부 운영자 인증 API는 일반 사용자 접근 불가
- 내부 운영자 계정은 90일 미사용 시 자동 잠금
프론트엔드 정책
- 내부 운영자용 UI와 환자용 UI 분리
- 사용자 유형에 따른 접근 가능 화면 제한
- 내부 운영자 로그인 시 추가 보안 요구사항 적용 가능
명령(Commands)
도메인 이벤트를 발생시키는 사용자 의도나 시스템 동작입니다.
백엔드 명령
| 명령 | 설명 | 영향 |
|---|---|---|
| RegisterDevice | 디바이스 등록 | DeviceRegistered 이벤트 발생 |
| IssueAppToken | 앱 토큰 발급 | AppTokenIssued 이벤트 발생 |
| VerifyAppIntegrity | 앱 무결성 검증 | AppIntegrityVerified 또는 AppIntegrityViolated 이벤트 발생 |
| GenerateChallenge | 보안 챌린지 생성 | ChallengeIssued 이벤트 발생 |
| VerifyChallenge | 챌린지 응답 검증 | ChallengeVerified 이벤트 발생 |
| BlacklistDevice | 디바이스 블랙리스트 추가 | DeviceBlacklisted 이벤트 발생 |
| ValidateAppToken | 앱 토큰 검증 | 앱 접근 허용 또는 거부 |
| LoginUser | 사용자 로그인 처리 | UserLoggedIn 또는 LoginFailed 이벤트 발생 |
| RefreshToken | 토큰 갱신 | TokenRefreshed 이벤트 발생 |
| RevokeToken | 토큰 폐기 | TokenRevoked 이벤트 발생 |
| InvalidatePreviousTokens | 이전 디바이스 토큰 무효화 | PreviousTokensInvalidated 이벤트 발생 |
| CheckActiveTokens | 활성 토큰 확인 | 현재 사용자의 활성 토큰 정보 제공 |
| ChangePassword | 비밀번호 변경 | PasswordChanged 이벤트 발생 |
| DisableMFA | 다중 인증 비활성화 | MfaDisabled 이벤트 발생 |
| VerifyMFA | 다중 인증 코드 검증 | MFAVerified 이벤트 발생 |
| ValidateTokenBlacklist | 토큰 블랙리스트 검증 | 토큰 유효성 확인 또는 거부 |
| ProcessOAuthLogin | OAuth 로그인 처리 | OAuthCallbackReceived 이벤트 발생 |
| LinkOAuthAccount | OAuth 계정 연동 | OAuthAccountLinked 이벤트 발생 |
| UnlinkOAuthAccount | OAuth 계정 연동 해제 | OAuthAccountUnlinked 이벤트 발생 |
| LockAccount | 계정 잠금 | AccountLocked 이벤트 발생 |
| UnlockAccount | 계정 잠금 해제 | AccountUnlocked 이벤트 발생 |
| RequestPasswordReset | 비밀번호 재설정 요청 | 이메일로 재설정 링크 발송 |
| ResetPassword | 비밀번호 재설정 | PasswordResetCompleted 이벤트 발생 |
| RequestEmailVerification | 이메일 인증 코드 발송 요청 | EmailVerificationCodeSent 이벤트 발생 |
| RequestEmailVerificationWithLanguage | 사용자 선호 언어로 이메일 인증 코드 발송 요청 | EmailVerificationCodeSentInUserLanguage 이벤트 발생 |
| ValidateEmailVerificationCode | 이메일 인증 코드 검증 | EmailVerificationCodeValidated 이벤트 발생 |
| RegisterUser | 사용자 회원가입 요청 (Access Code, 동의 정보 포함) | UserRegistrationCompleted 이벤트 발생 (User, Consent 도메인 협력) |
| OnboardGuest | 약관 동의만으로 게스트 계정 생성 | GuestOnboarded 또는 GuestOnboardingFailed 이벤트 발생 |
| InitializeStepUp | 게스트 Step-up 인증 세션 생성 | StepUpLinkSessionCreated 이벤트 발생 |
| ValidateStepUpAttempt | Step-up 인증 시도 검증 | StepUpRateLimited 이벤트 발생 가능 |
| CompleteStepUp | Step-up 인증 완료 처리 및 토큰 재발급 | StepUpCompleted, IdentityLevelChanged 이벤트 발생 |
| CancelStepUp | 진행 중인 Step-up 인증 세션 취소 | StepUpLinkSessionCancelled 이벤트 발생 |
| LinkGesundheitsID | GesundheitsID 연동 | GesundheitsIDLinked 이벤트 발생 |
| UnlinkGesundheitsID | GesundheitsID 연동 해제 | GesundheitsIDUnlinked 이벤트 발생 |
| LoginWithGesundheitsID | GesundheitsID로 로그인 | GesundheitsIDLoginSucceeded 또는 GesundheitsIDLoginFailed 이벤트 발생 |
| ValidateGesundheitsID | GesundheitsID 유효성 검증 | GesundheitsID 상태 확인 |
| ValidateAccessCode | 제출된 Access Code 검증 (Access Code 도메인 호출) | AccessCodeValidated 또는 AccessCodeValidationFailed 이벤트 발생 |
| RegisterOperationUser | 내부 운영자 사용자 등록 | OperationUserRegistered 이벤트 발생 |
| DeleteOperationUser | 내부 운영자 사용자 삭제 | OperationUserDeleted 이벤트 발생 |
| LoginOperationUser | 내부 운영자 로그인 처리 | OperationUserLoggedIn 또는 OperationUserLoginFailed 이벤트 발생 |
| LogoutOperationUser | 내부 운영자 로그아웃 처리 | OperationUserLoggedOut 이벤트 발생 |
| RefreshOperationToken | 내부 운영자 토큰 갱신 | OperationTokenRefreshed 이벤트 발생 |
| RequestOperationEmailVerification | 내부 운영자 이메일 인증 코드 발송 요청 | OperationEmailVerificationCodeSent 이벤트 발생 |
| ValidateOperationEmailVerificationCode | 내부 운영자 이메일 인증 코드 검증 | OperationEmailVerified 이벤트 발생 |
| ChangeUserType | 사용자 유형 변경 (환자/내부 운영자 간 전환) | UserTypeChanged 이벤트 발생 |
프론트엔드 명령
| 명령 | 설명 | 영향 |
|---|---|---|
| RequestDeviceRegistration | 디바이스 등록 요청 | 디바이스 정보 서버 전송 |
| RequestAppToken | 앱 토큰 요청 | 토큰 요청 전송 |
| SubmitChallengeResponse | 챌린지 응답 제출 | 챌린지 응답 서버 전송 |
| StoreAppToken | 앱 토큰 저장 | 안전한 저장소에 토큰 보관 |
| AttemptLogin | 사용자 로그인 시도 | LoginUser 명령 트리거 |
| StartGuestOnboarding | 게스트 온보딩 플로우 시작 | OnboardGuest 명령 트리거 |
| StartStepUpLink | Step-up 인증 세션 시작 | InitializeStepUp 명령 트리거 |
| SubmitStepUpVerification | Step-up 인증 증명 제출 | CompleteStepUp 명령 트리거 |
| CancelStepUpLink | Step-up 인증 세션 취소 | CancelStepUp 명령 트리거 |
| AutoLoginUser | 자동 로그인 시도 | LoginUser 명령 트리거 (저장된 정보 사용) |
| SetKeepLoginState | 로그인 상태 유지 설정 | 로컬 설정 변경 |
| LogoutUser | 사용자 로그아웃 요청 | LogoutUser 명령 트리거 |
| HandleAppBackground | 앱 백그라운드 전환 처리 | 보안 조치 적용 및 타이머 시작 |
| HandleAppForeground | 앱 포그라운드 전환 처리 | 세션 상태에 따른 인증 요청 |
| PerformSimpleAuth | 간편 인증 수행 (로컬) | PIN 또는 생체 인증 프롬프트 표시 |
| StartOAuthLogin | OAuth 로그인 시작 | 외부 인증 서비스로 리다이렉트 |
| HandleOAuthCallback | OAuth 콜백 처리 | ProcessOAuthLogin 명령 트리거 |
| SubmitPasswordResetRequest | 비밀번호 재설정 요청 제출 | RequestPasswordReset 명령 트리거 |
| SubmitNewPassword | 새 비밀번호 제출 | ResetPassword 명령 트리거 |
| RequestGesundheitsIDLink | GesundheitsID 연동 요청 | LinkGesundheitsID 명령 트리거 |
| RequestGesundheitsIDUnlink | GesundheitsID 연동 해제 요청 | UnlinkGesundheitsID 명령 트리거 |
| AttemptGesundheitsIDLogin | GesundheitsID 로그인 시도 | LoginWithGesundheitsID 명령 트리거 |
| DisplayGesundheitsIDSettings | GesundheitsID 설정 표시 | GesundheitsID 관리 화면 렌더링 |
액터(Actors)
시스템과 상호작용하는 주체들입니다.
내부 액터
| 액터 | 설명 | 주요 명령 |
|---|---|---|
| 일반 사용자(환자) | 시스템 이용자 | 로그인/로그아웃, 비밀번호 변경, MFA/PIN 설정, OAuth 연동 |
| 내부 운영자 | 시스템 내부 운영 담당자 | 내부 운영자 로그인/로그아웃, 비밀번호 변경, 관리 기능 접근 |
| 시스템 관리자 | 인증 시스템 관리자 | 계정 잠금/해제, 보안 설정, 디바이스 관리, 내부 운영자 관리 |
| 보안 관리자 | 보안 정책 관리자 | 보안 정책 설정, 위반 대응 |
외부 액터
| 액터 | 설명 | 주요 명령 |
|---|---|---|
| GesundheitsID (OAuth 제공자) | 외부 인증 서비스 | OAuth 인증 처리 응답 |
| 알림 서비스 (SMS/Email) | 보안 알림 전송 | 알림 발송 요청 수신 |
집계(Aggregates)
연관된 엔티티와 값 객체들의 클러스터입니다.
AuthToken 집계
- 루트: TokenBlacklist
- 엔티티: Token, LoginAttempt
- 값 객체: TokenStatus, TokenType, DeviceInfo, IpAddress
- 불변식:
- 사용자는 하나의 활성 토큰만 가질 수 있음
- 블랙리스트된 토큰은 모든 요청에서 거부
- 보안 위반 시 즉시 토큰 블랙리스트 추가
- 한 사용자는 한 번에 하나의 활성 토큰(디바이스)만 가질 수 있음 (정책)
UserCredential 집계
- 루트: Credential (또는 User Aggregate의 일부일 수 있음)
- 엔티티: Password, MFAConfig, SecurityQuestion (필요시)
- 값 객체: PasswordHash, MFASecret, LockoutStatus
- 불변식:
- 비밀번호는 항상 해시되어 저장
- MFA 설정은 사용자당 하나만 가능
- 보안 정책을 준수하는 비밀번호만 허용
- 연속된 인증 실패 시 LockoutStatus 변경
OAuthProvider 집계
- 루트: OAuthProvider (예: GesundheitsID)
- 엔티티: OAuthConfig, OAuthToken (사용자별 토큰 정보)
- 값 객체: ProviderType, OAuthScope, ClientId, ClientSecret
- 불변식:
- 제공자별 설정은 유일해야 함
- OAuth 토큰은 항상 암호화되어 저장
- 특정 사용자에 대해 연동된 OAuth 제공자는 유일해야 함
AppSecurity 집계
- 루트: Device
- 엔티티: AppToken, Challenge
- 값 객체: DeviceIdentifier (Hashed), Platform, AppVersion, ChallengeResponse, BlacklistStatus
- 불변식:
- 디바이스 ID는 항상 해싱되어 저장됨
- 앱 토큰은 검증된 디바이스에만 발급
- 챌린지는 일회용이며 시간 제한이 있음
- 무결성 검증에 실패한 앱은 토큰 발급 불가
- 블랙리스트된 디바이스는 인증 불가
UserType 집계
- 루트: UserType
- 값 객체: UserTypeEnum (PATIENT, ADMIN, OPERATOR, CLINICIAN, SERVICE_ACCOUNT)
- 불변식:
- 사용자는 하나의 유형만 가질 수 있음
- 유형 변경은 SYSTEM_ADMIN만 가능
- 유형에 따라 적절한 스키마 선택 (PATIENT -> private, 그 외 -> operation)
- 유형 변경 시 데이터 마이그레이션 필요
핫스팟 및 해결책
1. 세션 관리 확장성
문제: 대규모 동시 세션 관리의 어려움 해결책:
- Redis 기반 세션 저장소 사용
- 세션 클러스터링
- 세션 정리 배치 처리
2. OAuth 통합 복잡성
문제: 특정 OAuth 제공자(GesundheitsID) 연동 및 유지보수 해결책:
- 제공자별 어댑터 패턴 적용
- 공통 인터페이스 정의
- 설정 추상화
3. MFA 구현 복잡성
문제: 다양한 MFA 방식 지원의 어려움 (현재는 특정 방식만 요구) 해결책:
- 전략 패턴을 통한 MFA 구현 (향후 확장 고려)
- 플러그인 아키텍처 적용
- 확장 가능한 인터페이스 설계
4. 토큰 관리 보안
문제: 토큰의 안전한 저장과 검증 해결책:
- 토큰 서명 및 검증 강화 (비대칭 키 사용 고려)
- 토큰 회전 정책 구현
- 리프레시 토큰 탈취 방지 메커니즘
5. 앱 무결성 검증
문제: 클라이언트 앱의 무결성을 신뢰할 수 없음 해결책:
- 시간 기반 챌린지-응답 메커니즘 구현
- 디바이스 정보 해싱 및 검증
- 무결성 검증 실패 시 자동 차단
6. 디바이스 식별 보안
문제: 디바이스 ID의 안전한 관리 및 검증 해결책:
- 디바이스 ID SHA-256 해싱 적용
- 앱 시크릿을 사용한 솔트 추가 (선택 사항)
- 원본 디바이스 정보 직접 노출 방지
7. 사용자 유형 분리 관리
문제: 환자와 내부 운영자 데이터의 분리된 스키마 관리 및 인증 통합 해결책:
- 공통 인증 서비스와 유형별 처리 전략 패턴 적용
- 사용자 유형에 따른 데이터 액세스 추상화
- 유형 변경 시 데이터 마이그레이션 프로세스 정의
8. MAO 티어/동의/라우팅 이벤트
- AnonymousIssued: 유효한 appToken 인증을 통과한 클라이언트가 anonymous 토큰을 발급받음(
tier=anonymous,allowed_domains=["faq","docs-public","agent-help-public"],data_persistence=none), 컨텍스트는 NOT_READY. - GuestIssued: tier=
guest, consent_version 포함 토큰 발급 - GuestUpgradedToMember: guest→member 승격 시 기존 토큰 폐기 및 재발급
- ConsentVersionMismatchDetected: 토큰의 consent_version이 최신과 불일치하여 재동의 필요
- AnonymousRouted: tier 누락/anonymous로 간주되어 MAO가 컨텍스트 없이 라우팅
- AllowedDomainsUpdated: allowed_domains/data_persistence 정책 변경 시 토큰 재검증 트리거
변경 이력
| 버전 | 날짜 | 작성자 | 변경 내용 |
|---|---|---|---|
| 0.1.0 | 2025-03-25 | bok@weltcorp.com | 최초 작성 |
| 0.2.0 | 2025-04-29 | bok@weltcorp.com | Terms 및 Consent 관련 내용 분리, 바운디드 컨텍스트 참조 업데이트 |
| 0.3.0 | 2025-05-07 | bok@weltcorp.com | 사용자 유형 분리(환자/내부 운영자) 관련 내용 추가 |
| 0.4.0 | 2025-01-16 | AI Assistant | JWT stateless 인증 방식에 맞게 이벤트 스토밍 수정: 세션 관리 정책 → 토큰 관리 정책, AuthSession 집계 → AuthToken 집계, 세션 관련 명령/이벤트를 토큰 중심으로 변경 |
| 0.5.0 | 2025-11-26 | bok@weltcorp.com | MAO 라우팅을 위한 guest/anonymous/consent 이벤트 추가 (GuestIssued, GuestUpgradedToMember 등) |
| 0.6.0 | 2025-11-26 | bok@weltcorp.com | AnonymousIssued 이벤트에 appToken 인증 요구 및 기본 클레임 명시 |