KR Kakao 인증 도메인 모델
데이터 저장 규칙
- Kakao 인가 세션(state/nonce)은 Redis 네임스페이스
auth:kr:kakao:session:*에 저장한다. (business-rules.md 2.2) - Kakao 리프레시 토큰(LTV)은 PostgreSQL
auth.external_identity_tokens테이블 혹은 Redisauth:kr:kakao:token:*에 암호화된 상태로 저장한다. (business-rules.md 3) - 외부 식별자 연결(
ExternalIdentityLink)은auth.external_identity테이블 중 Kakao 공급자 레코드로 관리하며, 공급자 정의는auth.external_identity_provider테이블에서 가져온다. - 감사 로그 및 이벤트 타임라인은 TimeMachine 기반 시각을 사용하며,
audit_log스키마에 기록된다. - 본 문서의 스키마 예시는 KR Kakao 컨텍스트에서 직접 소유·관리하는 테이블 또는 키 공간만 포함한다.
1. 엔티티 관계도 (ERD)
참고:
KAKAO_AUTH_SESSION은 Redis 기반 임시 세션으로 표기했으며,EXTERNAL_IDENTITY·KAKAO_REFRESH_TOKEN은 공통 공유 스키마에 존재하지만 Kakao 공급자 데이터를 KR 컨텍스트에서 책임진다.
2. 애그리게이트 (Aggregates)
| Aggregate | 설명 | 루트 엔티티 | 영속 위치 | 트리거 이벤트 |
|---|---|---|---|---|
KakaoAuthSession | 인가 요청 동안 state/nonce를 관리하고 유효성 검증을 수행한다. | sessionId | Redis (auth:kr:kakao:session:{id}) | KakaoAuthSessionCreatedEvent, KakaoAuthSessionExpiredEvent |
ExternalIdentityLink | Kakao 사용자 ID와 내부 사용자 계정을 연결한다. | externalIdentityId | external_identity (providerCode=kakao) | ExternalAuthLinkedEvent, ExternalAuthUnlinkedEvent |
KakaoRefreshTokenProjection | Kakao 리프레시 토큰 보관 및 갱신 시점을 관리한다. | externalIdentityTokenId | external_identity_tokens | KakaoRefreshTokenStoredEvent, KakaoRefreshTokenRotatedEvent |
3. 엔티티
3.1 KakaoAuthSession (Redis View)
interface KakaoAuthSession {
sessionId: string; // UUID
state: string; // random string
nonce: string; // random string
requestedScopes: string[];
redirectUri: string;
expireAt: Date; // TimeMachine 기준
createdAt: Date;
}
- TTL: 기본 10분, 만료 시 만료 워커가
KakaoAuthSessionExpiredEvent발행. - Validation:
state·nonce·redirectUri필수. (business-rules.md 2)
3.2 ExternalIdentityProviderEntry
interface ExternalIdentityProviderEntry {
code: 'kakao';
displayName: string;
region: 'kr';
isActive: boolean;
metadata?: {
scopes?: string[];
consentUrl?: string;
};
}
- 공급자 코드 등록 및 비활성화 절차는 공통 문서의 ExternalIdentityProvider 운영 절차 를 따른다.
auth.external_identity_provider테이블에서 관리하며, 공통 도메인과 공유한다.- 메타데이터에는 동의 문구, OAuth scope, UI 라벨 등을 저장한다.
3.3 ExternalIdentityLink
interface ExternalIdentityLink {
externalIdentityId: string;
userId: string;
providerCode: 'kakao'; // auth.external_identity_provider.code
kakaoUserId: KakaoUserId; // 암호화된 Value Object
linkedAt: Date;
linkedBy: string; // 'self' | 'operator'
}
- 유일성:
kakaoUserId는 하나의 내부userId에만 연결 가능. (business-rules.md 2.5)
3.4 KakaoRefreshTokenProjection
interface KakaoRefreshTokenProjection {
id: string;
externalIdentityId: string;
refreshTokenCipher: string; // 암호화 저장
expiresAt: Date;
lastRotatedAt: Date;
issuedBy: string;
}
- Rotation Policy: 만료 5분 전 1회만 갱신. 실패 시
SessionExpiredEvent발행. (business-rules.md 2.6)
4. 값 객체 (Value Objects)
| 이름 | 타입 | 설명 | 검증 |
|---|---|---|---|
KakaoAuthSessionId | UUID | Redis 세션 키 식별자 | UUID v4 |
KakaoUserId | 암호화 문자열 | Kakao 사용자 식별자, 암호화 저장 | Non-empty |
AuthProviderRegion | Enum (KR) | 공급자 지역 태그 | KR 고정 |
IdempotencyKey | 문자열 | kakao:{state} 패턴 | 정규식 ^kakao:[a-zA-Z0-9_-]+$ |
5. 도메인 서비스 및 정책
| 서비스 | 역할 | 의존성 |
|---|---|---|
InitiateKakaoAuthService | KakaoAuthSession 생성, ACL에 인가 URL 구성 위임 | TimeMachine, Redis, KakaoOAuthHttpClient |
CompleteKakaoAuthService | state 검증, 토큰 교환, JWT 발급 오케스트레이션 | TimeMachine, Redis, ACL, Auth Core의 IssueSessionService |
LinkKakaoIdentityPolicy | Kakao ID 중복 여부 검증, 연결/재연결 처리 | ExternalIdentityRepository, Redis |
KakaoTokenRotationService | 만료 임박 토큰 갱신, 실패 시 이벤트 발행 | TimeMachine, ACL, Redis |
6. 도메인 이벤트
| 이벤트 | 발생 시점 | 페이로드 | 다운스트림 |
|---|---|---|---|
KakaoAuthSessionCreatedEvent | 인가 요청 처리 완료 | sessionId, state, expireAt | 모니터링, 만료 워커 |
KakaoAuthSessionExpiredEvent | TTL 만료 워커 실행 | sessionId, state | 감사 로그 |
KakaoAuthCompletedEvent | 토큰 교환 및 JWT 발급 성공 | userId, kakaoUserId, sessionId | Notification, Analytics |
ExternalAuthLinkedEvent | Kakao ID 연결 완료 | userId, provider, linkedAt | User Profile, CRM |
ExternalAuthUnlinkedEvent | 연결 해제 | userId, provider, reason | Audit, Notification |
KakaoProviderUnavailableEvent | Kakao API 5xx | correlationId, retryAfter | Ops 알림, Feature flag 조정 |
UserProvisionRequiredEvent | 신규 사용자가 연결 되었으나 프로필 없음 | kakaoUserId, appTokenId, provisionContext | User Provisioning |
7. 인변조건 (Invariants)
- 하나의
KakaoAuthSession은state·nonce·expireAt이 모두 존재해야 하며, 만료 전 콜백이 오지 않으면 자동 삭제되어야 한다. KakaoUserId는 시스템 내에서 단일 내부 사용자와만 연결될 수 있다.- 동일 사용자와 공급자 조합은 하나의
ExternalIdentity레코드만 허용되며, (providerCode,userId) 유니크 제약으로 enforced 된다. - 모든 Timestamp는 TimeMachine 기반이어야 하며, 시스템 시계를 직접 호출해서는 안 된다.
- Redis idempotency 키가 존재하는 경우 동일 콜백은 재처리하지 않는다.
8. Prisma/Schema 참고
auth.external_identity_provider,auth.external_identity,auth.external_identity_tokens테이블 스키마는 공통 인증 도메인 문서를 참조한다.- KR 컨텍스트에서 추가로 필요한 필드는 공통 스키마 확장 제안을 통해 진행한다.
9. 변경 이력
| 버전 | 날짜 | 작성자 | 변경 내용 |
|---|---|---|---|
| 0.1.0 | 2025-10-21 | bok@weltcorp.com | 도메인 모델 문서 재구성 |