본문으로 건너뛰기

게스트 Step-up 인증 및 identityLevel 확장 설계

개요

게스트 계정 확장 요구사항에 따라 Auth·IAM 경계에서는 아래 사항을 충족해야 합니다.

  • 이메일/카카오 연동 없이 약관 동의만으로 발급되는 게스트 토큰의 안전한 수명 관리
  • 정규 인증으로 승격(이하 Step-up) 시 기존 게스트 세션을 폐기하고 신규 신원 수준을 반영하는 계약
  • Access/Refresh Token, 권한 평가, 이벤트 기반 싱크에서 identityLevel을 일관되게 사용
  • 타 도메인(User, Group, Plan)과의 상태 전이를 비동기 이벤트로 확정

본 문서는 토큰 스키마, API 계약, 이벤트 흐름, IAM 연동 지침을 정의합니다.

핵심 설계 원칙: 게스트 아키텍처 (v1.2.0)

중요: 게스트 계정도 정식 사용자와 동일하게 User + UserCycle 레코드를 생성합니다. 게스트와 정식 사용자의 구분은 accountType 필드가 아닌 IAM GroupPlan으로 관리합니다.

게스트 등록 시 생성되는 데이터

데이터설명
User게스트도 정식 User 레코드 생성 (UUID 발급)
UserCycle치료 사이클 관리를 위한 UserCycle 생성
GuestAccountLifecycle게스트 생명주기 이벤트 기록 (만료, 업그레이드 추적)
IAM Group 할당guests 또는 guests.{region} 그룹 할당
Plan 할당plan.guest 플랜 할당

Step-up 시 변경 사항 (userId 유지)

항목변경 전변경 후
userIdabc-123abc-123 (유지)
IAM Groupguests.krpatients.kr, patients.general (예시)
Planplan.guestplan.therapeutic (예시)
identityLevelguestregistered
기존 데이터수면 기록, 설문 등그대로 연결됨 (userId 동일)

이 설계의 핵심 장점은 Step-up 시 userId가 변경되지 않아 기존 데이터가 자연스럽게 연결된다는 것입니다.

IAM Group 체계

게스트와 정식 사용자의 구분은 IAM Group으로 관리합니다.

게스트 그룹 (guests.*)

그룹설명
guests게스트 기본 그룹
guests.kr한국 지역 게스트
guests.de독일 지역 게스트
guests.us미국 지역 게스트
guests.jp일본 지역 게스트

정식 사용자 그룹 (Step-up 후)

Step-up 후 할당되는 그룹은 사용 목적에 따라 다양합니다. patients.*는 대표적인 예시일 뿐이며, 비즈니스 요구사항에 따라 다른 그룹으로 할당될 수 있습니다.

그룹 패턴설명예시
patients.*일반 치료 환자 그룹patients.kr, patients.de, patients.general
clinical-trial.*임상시험 참가자 그룹clinical-trial.study-001, clinical-trial.phase-2
research.*연구 대상자 그룹research.sleep-study, research.pilot
enterprise.*기업 고객 그룹enterprise.company-a, enterprise.wellness
special.*특수 목적 그룹special.beta-tester, special.vip

중요: 게스트 여부 판별은 guests.* 그룹 소속 여부로만 판단합니다. 정식 사용자는 "특정 그룹에 속함"이 아니라 *"guests. 그룹에 속하지 않음"**으로 판별합니다.

// 게스트 판별 로직 (올바른 예)
const isGuest = roles.some(role => role.startsWith('guests.'));

// 잘못된 예 - patients만 정식 사용자로 간주
// const isRegistered = roles.some(role => role.startsWith('patients.')); // ❌

토큰 스키마 확장

항목설명게스트정규 사용자
identityLevel (Access Token Claim)신원 검증 수준. IAM 정책 계산 및 기능 Gate에 사용guest 고정registered 또는 상위 수준(OAuth, 2FA 등)
consents약관·선택 동의 집합. 게스트는 필수 약관만 보유필수 약관 최소화정규 프로필 기준
identityBindings (Refresh Token Meta)연결된 인증 수단 목록(email, kakao 등)빈 배열적어도 하나 이상
deviceBinding토큰을 발급한 App Token/Device ID최초 온보딩 디바이스로 고정마지막 인증 디바이스로 갱신 가능
  • Access Token 예시 (요약):
{
"sub": "550e8400-e29b-41d4-a716-446655440000",
"identityLevel": "guest",
"guestAccountId": "guest-4f52c7fa",
"groupIds": ["guests.kr"],
"planId": "plan.guest",
"consents": ["terms.v1.accepted"],
"deviceBinding": "appToken:abc123",
"exp": 1692698400,
"iat": 1692697500,
"aud": ["dta-wide-api"]
}

참고: sub 필드는 User 테이블의 UUID입니다. 게스트도 정식 User 레코드가 생성되므로 UUID가 발급됩니다. guestAccountId는 게스트 생명주기 추적을 위한 별도 식별자입니다.

  • Refresh Token 메타 예시:
{
"identityLevel": "guest",
"identityBindings": [],
"deviceBinding": "device:5f92c1"
}

토큰 저장소는 identityLeveldeviceBinding을 키로 함께 인덱싱하여 게스트 토큰 재사용을 감시합니다.

API 계약

1. 게스트 등록 (POST /auth/guest/register)

  • 입력: App Token, User-Agent 헤더, 디바이스 정보 (uuid), 약관 동의 목록 (agreements), 프로필 정보 (profile).
  • 검증:
    • AppTokenGuard로 앱 무결성 확인.
    • 이미 등록된 디바이스와의 중복 여부 확인.
    • 지역별 동의 정책(Group/Plan 의존) 충족.
    • User-Agent 헤더에서 region, platform, appVersion 등 자동 추출.
    • profile.languageprofile.timezone 필수 검증.
  • 처리 (v1.2.0 업데이트):
    1. User 레코드 생성: UUID 발급, 기본 프로필 설정
    2. UserCycle 레코드 생성: 치료 사이클 관리 시작
    3. GuestAccountLifecycle 이벤트 기록: ONBOARDED 이벤트
    4. IAM Group 할당: User-Agent에서 추출한 region에 따라 guests.{region} 그룹 할당
    5. Plan 할당: plan.guest 플랜 할당
    6. 만료 타이머 스케줄링: TimeMachine/Cloud Scheduler로 서비스 설정에 따른 만료 예약
  • 출력:
    • Access Token (identityLevel=guest, sub=userId, TTL ≤ 15분)
    • Refresh Token (TTL ≤ 12시간)
    • userId (User 테이블의 UUID - Step-up 이후에도 유지됨)
    • guestAccountId (게스트 생명주기 추적용)
  • 감사 로그: auth.guest.registered (userId, guestAccountId, region, agreements, profile)

2. Step-up 인증 준비 (POST /auth/guest/link/init)

  • 게스트가 이메일 또는 카카오 연동을 선택하면, Auth는 적절한 1차 인증(이메일 코드, OAuth state) 플로우를 시작합니다.
  • 출력: linkSessionId, 만료 시간, 선택된 인증 수단.
  • 제약: 게스트 토큰과 동일 디바이스에서만 호출 가능.

3. Step-up 인증 완료 (POST /auth/guest/link/complete)

  • 입력: linkSessionId, 인증 증명(이메일 코드/카카오 Authorization Code 등), 최신 Refresh Token.
  • 처리 (v1.2.0 업데이트 - userId 유지):
    1. 인증 증명 검증 → 신규 credentialId 발급.
    2. 기존 Refresh Token과 Access Token을 모두 블랙리스트 처리.
    3. User 도메인에 user.identity-level-upgrade.requested 명령 이벤트 발행.
    4. Group 변경: guests.{region}patients.{region}, patients.general
    5. Plan 변경: plan.guestplan.therapeutic
    6. GuestAccountLifecycle 기록: UPGRADED 이벤트
    7. 만료 타이머 해제: 게스트 만료 스케줄 취소
    8. 신규 Access/Refresh Token 발급 (identityLevel=registered, 동일한 sub=userId).
  • 핵심: userId(UUID)는 변경되지 않음 - 게스트 기간 동안 생성된 모든 데이터가 자동으로 연결됨
  • 출력: 신규 토큰 페어 (동일 userId), 업그레이드 요약(필수 약관 추가 여부, 다음 단계 안내).

4. Link 해제 (POST /auth/guest/link/cancel)

  • 인증 진행 중인 세션을 취소하고, linkSessionId와 연계된 임시 리소스를 정리합니다.

시퀀스 다이어그램

게스트 등록 플로우 (v1.2.0)

Step-up 인증 플로우 (v1.2.0 - userId 유지)

이벤트 계약

이벤트발행자목적필드
auth.guest.registeredAuth게스트 생성 감사 및 분석 (v1.2.0: userId 포함)userId, guestAccountId, region, deviceFingerprint, agreements, profile, groupIds, planId, timeMachineTick
user.identity-level-upgrade.requestedAuthUser 도메인에 Group/Plan 전환 명령 (userId 유지)userId, guestAccountId, credentialType, credentialId, targetGroupIds, targetPlanId, timeMachineTick
user.identity-level-upgrade.confirmedUserAuth에 게스트→정규 사용자 전환 확정 통보 (동일 userId)userId, previousGroupIds, newGroupIds, previousPlanId, newPlanId, timeMachineTick
auth.identity-level.changedAuthIAM·Plan·Group 캐시 동기화userId, identityLevel, bindings, planId, groupIds, revokedRefreshTokens
iam.access-cache.invalidateIAM권한 캐시 무효화 트리거userId, invalidateReason, timeMachineTick

v1.2.0 변경사항: auth.guest.registered 이벤트에 userId가 추가되었습니다. 게스트 등록 시점에 User 레코드가 생성되므로 모든 이벤트에서 동일한 userId를 사용합니다.

모든 이벤트는 TimeMachineService의 tick 값을 포함해 재현 가능한 타임라인을 보장합니다.

IAM 연동 지침

  1. 권한 평가 입력 확장
    AccessEvaluationRequestidentityLevelplanId, groupIds를 함께 전달합니다. 게스트 토큰의 경우 planId=plan.guest.default 형태로 관리합니다.

  2. 정책 표현식

    • 게스트 차단 자원: requiresIdentityLevel >= registered
    • 게스트 허용 자원: identityLevel == guest && permission in guestAllowList
  3. 캐시 무효화

    • auth.identity-level.changed 수신 시 사용자별 권한 캐시를 전량 폐기합니다.
    • revokedRefreshTokens 목록을 통해 기존 세션을 추적하고, API Gateway 레벨에서 블랙리스트 반영.
  4. 감사 로깅
    게스트 승격 시 iam.audit 로그에 이전/이후 권한 스냅샷을 저장하여 추적성을 확보합니다.

보안 고려사항

  • 게스트 Refresh Token은 단일 디바이스에서만 갱신 가능하도록 deviceBinding을 검증합니다.
  • Step-up 완료 시, 게스트 토큰은 즉시 블랙리스트에 추가하고 TTL이 만료되기 전이라도 사용을 거부합니다.
  • 동일 디바이스에서 3회 이상 Step-up 실패 시 계정을 LOCKED 상태로 전환하며, 추가 인증 절차(고객센터) 안내를 반환합니다.
  • OAuth Step-up의 경우 state 파라미터에 guestAccountId를 포함하되, 서명된 JWT 형태로 전달해 위변조를 방지합니다.

미해결 과제

  • 헬스케어 규제에 따른 게스트 상태 허용 범위(예: 진단 데이터 접근) 세부 정의.
  • Step-up 실패 시 재시도 백오프 정책과 UI 메시지 표준화.
  • 게스트와 정규 사용자 간 동의 항목 차등 적용에 대한 Legal 검토.

구현 및 테스트 계획

1. 구현 단계

  1. 데이터 모델 확장 (v1.2.0 업데이트)
    • User: 게스트도 정식 User + UserCycle 레코드 생성. GuestAccountLifecycle 테이블로 생명주기 추적.
    • Plan: plan.guest 플랜 생성 (서비스 정책에 따른 제한된 기능 및 이용 기간).
    • Group: guests, guests.kr, guests.de, guests.us, guests.jp 그룹 시드 데이터 생성.
  2. Auth 서비스 업데이트
    • guest/register, guest/link/* API 구현.
    • identityLevel 클레임 포함 Access/Refresh Token 발급.
    • Step-up 완료 시 auth.identity-level.changed 이벤트 발행.
  3. User/Group/Plan/IAM 연동
    • User: 게스트 만료 타이머 스케줄링, Step-up 수신 핸들러, 게스트 정리 워커 구현.
    • Group: 게스트 자동 할당, Step-up 이관, 만료 정리 핸들러 구현.
    • Plan: 게스트 플랜 할당/전환, 만료 정리 로직 구현.
    • IAM: identityLevel 기반 인가 평가 및 캐시 무효화 구현.
  4. Backlog 태스크 매핑
    • task-1 Implement guest plan/group automation
    • task-2 Automate guest expiry and upgrade nudges
    • 추가 태스크: IAM identityLevel 평가, Auth API 구현, Frontend Step-up UX (추가 생성 필요)

2. 테스트 전략

레벨범위주요 시나리오
단위(Unit)Auth/Plan/Group/IAM 서비스게스트 토큰 발급, Step-up 완료, 권한 평가, 만료 정리 로직
통합(Integration)Auth ↔ User ↔ Group ↔ Plan ↔ IAMauth.guest.onboarded부터 Step-up 완료, 만료 정리까지 이벤트 흐름
E2E모바일 앱+백엔드게스트 온보딩 → 기능 제한 → Step-up → 정규 기능 접근, 만료 후 접근 차단
회귀(Regressions)기존 사용자 가입/로그인기존 플로우가 영향받지 않는지 확인

3. 검증 체크리스트

구현 완료 (v1.2.0)

  • 게스트 토큰이 identityLevel=guest로 발급되고 권한 평가에서 제한되는지 확인
  • TimeMachine 기반 만료 이벤트가 예정 시간에 실행되는지 확인 (GuestExpirySchedulerService)
  • Audit 로그 및 GuestAccountLifecycle 레코드가 누락 없이 생성되는지 확인
  • (v1.2.0) 게스트 등록 시 User + UserCycle 레코드가 정상 생성되는지 확인 (GuestCreationService)
  • (v1.2.0) 게스트 자발적 탈퇴 시 만료 타이머 해제 및 VOLUNTARILY_WITHDRAWN 이벤트 기록

TODO: Step-up 인증 구현 필요

  • Step-up 완료 시 모든 게스트 토큰이 블랙리스트 처리되는지 확인
  • User/Group/Plan에서 게스트 → 등록 전환 이력이 정확히 기록되는지 확인
  • IAM POST /v1/iam/access/evaluate API가 게스트와 정규 사용자 모두 정확한 결과를 반환하는지 확인
  • (v1.2.0) Step-up 시 userId가 변경되지 않고 기존 데이터와 연결되는지 확인
  • (v1.2.0) 게스트 그룹(guests.*)이 정식 그룹으로 올바르게 변경되는지 확인

Step-up API 구현 TODO

POST /auth/guest/link/init     - Step-up 인증 준비
POST /auth/guest/link/complete - Step-up 인증 완료
POST /auth/guest/link/cancel - Step-up 인증 취소

변경 이력

버전날짜작성자변경 내용
1.0.02025-04-20bok@weltcorp.com최초 문서 생성
1.1.02025-05-15bok@weltcorp.comStep-up 인증 플로우 상세화
1.2.02025-12-17bok@weltcorp.com게스트 아키텍처 개선: 게스트도 User+UserCycle 생성, IAM Group 기반 분류(guests.*), Plan 기반 기능 제어(plan.guest), Step-up 시 userId 유지
1.2.12025-12-18bok@weltcorp.com구현 상태 반영: 게스트 등록/만료/자발적 탈퇴 완료, Step-up 인증 TODO 명시
1.2.22025-12-18bok@weltcorp.comIAM Group 체계 문서화: 정식 사용자 그룹 다양성 명시 (patients.* 외 clinical-trial., research., enterprise., special. 등), 게스트 판별 로직 가이드 추가