페이지 이동경로
  • 문서>
  • 카카오 로그인>
  • 보안 이벤트 구독

카카오 로그인

보안 이벤트 구독

이 문서는 카카오 로그인의 보안 이벤트 구독 기능 사용 방법을 안내합니다.

기능 소개

보안 이벤트 구독은 카카오 로그인 사용 서비스에 사용자의 보안 이벤트 정보를 전달하는 기능입니다. OpenID 재단의 SSE(Shared Signals and Events) 규격을 바탕으로 설계됐으며, 서비스에서 보다 적극적인 보안 조치를 취할 수 있도록 지원합니다. 예를 들면 앱 연결 및 해제, 비밀번호 변경, 비활성화와 같은 사용자의 보안 이벤트 정보를 제공받아 참고할 수 있습니다.

보안 이벤트 정보는 보안 이벤트 토큰(Security Event Token, 이하 SET) 형식으로 서비스에 전달됩니다. 서비스는 콜백 URL을 통해 전달받은 SET을 보안 이벤트 수신의 안내에 따라 처리해야 합니다.

참고: 보안 이벤트 구독 시스템의 SET 전달 과정
  1. 사용자의 보안 이벤트 정보를 수신합니다.
  2. 보안 이벤트 정보를 지정된 규격의 SET를 발급합니다.
  3. 서비스의 콜백 URL로 SET를 푸시(Push) 전송합니다.

시작하기 전에

사용 방법

보안 이벤트 구독 기능을 사용하려면 다음 순서로 앱 설정과 기능 구현을 진행합니다.

  1. 보안 이벤트 타입을 검토해 제공받을 정보 선택
  2. 앱 설정
  3. 메타데이터 조회를 통해 카카오 로그인의 보안 이벤트 구독 시스템 규격 확인
  4. 콜백 URL을 통해 전달받은 SET을 검증하고 처리하는 기능 구현, 보안 이벤트 수신 참고
  5. 설정 및 기능 구현이 올바른지 테스트

보안 이벤트 구독 설정

[내 애플리케이션] > [카카오 로그인] > [보안 이벤트 구독]에서 보안 이벤트 정보를 수신할 콜백 URL과 구독할 이벤트 타입을 설정해야 합니다. 자세한 안내는 설정하기를 참고합니다.

동의 항목 설정

일부 카테고리의 보안 이벤트 정보 제공에는 동의 항목 설정 및 사용자 동의가 필요합니다.

카테고리 동의 항목 설정 및 사용자 동의 설명
OAUTH 불필요 -
CAEP 필요 사용자의 동의가 있어야 서비스에 제공할 수 있는 민감 정보
필요 시 데브톡으로 문의해 권한 신청
권한을 받은 후 [내 애플리케이션] > [카카오 로그인] > [동의항목]에서 [보안 이벤트 정보 제공]을 [선택] 동의 단계로 설정, 설정하기 참고

비고:
[보안 이벤트 정보 제공]은 선택 동의로만 설정 가능해 사용자가 동의하지 않을 수 있음
[보안 이벤트 정보 제공]에 동의하지 않은 사용자의 CAEP, RISC 카테고리 보안 이벤트 정보 제공 불가
RISC

메타데이터 조회

보안 이벤트 구독 시스템의 규격을 확인하려면 아래와 같이 요청합니다.

GET https://kauth.kakao.com/.well-known/sse-configuration

아래는 응답 상세 정보와 예제입니다.

Name Type Description Required
issuer String SET 발급자
https://kauth.kakao.com로 고정
O
jwks_uri String SET 암호화 공개키 조회 URI
공개키는 SET 검증 시 필요
O
delivery_methods_supported String 지원하는 SSE 이벤트 전송 방식
push만 지원
O
HTTP/1.1 200 OK
{
    "issuer": "https://kauth.kakao.com",
    "jwks_uri": "https://kauth.kakao.com/.well-known/jwks.json",
    "delivery_methods_supported": "http://schemas.openid.net/secevent/risc/delivery-method/push"
}

보안 이벤트 타입

보안 이벤트 구독 시스템은 다음과 같은 보안 이벤트 정보를 서비스에 전달합니다.

카테고리 설명
OAUTH 카카오 로그인 사용자의 앱 연결 및 해제, 동의 항목 동의 및 철회, 토큰에 대한 보안 이벤트
CAEP(Continuous Access Evaluation Protocol)* 사용자 카카오계정에 발급된 자격증명(Token)에 대한 보안 이벤트
RISC(Risk Incident Sharing and Coordination)* 사용자 카카오계정의 이상징후 보안 이벤트

* 기본 제공되지 않음, 동의 항목 설정 참고

다음은 카테고리별 보안 이벤트 타입 목록입니다.

카테고리 타입 설명
OAUTH Tokens Revoked 카카오 로그인을 통해 발급된 사용자의 모든 토큰 만료

필수 보안 조치: 현재 열려 있는 서비스 세션을 종료하여 사용자 계정 보호
Schema: https://schemas.openid.net/secevent/oauth/event-type/tokens-revoked
User Linked 사용자가 앱과 연결

권장 보안 조치: [로그인 시 앱 자동 연결]을 [사용안함]으로 설정한 앱인 경우, 회원 가입 완료 처리 외 서비스에서 필요한 조치 수행
Schema: https://schemas.openid.net/secevent/oauth/event-type/user-linked
User Unlinked 사용자가 앱과 연결 해제

권장 보안 조치: 사용자 회원 정보의 카카오 로그인 연동을 해제하거나, 카카오 로그인으로만 이용 가능한 경우에는 회원 탈퇴 처리(참고: 연결 끊기 알림)
Schema: https://schemas.openid.net/secevent/oauth/event-type/user-unlinked
User Scope Consent 사용자가 동의 항목에 동의

Schema: https://schemas.openid.net/secevent/oauth/event-type/user-scope-consent
User Scope Withdraw 사용자가 동의 항목 동의 철회

Schema: https://schemas.openid.net/secevent/oauth/event-type/user-scope-withdraw
RISC Account Credential Change Required 계정 비밀번호 변경 필요

권장 보안 조치: 서비스에서 의심스러운 활동이 있는지 확인하여 필요한 후속 조치 결정
Schema: https://schemas.openid.net/secevent/risc/event-type/account-credential-change-required
Account Disabled 계정 비활성화
카카오계정 보호 조치, 잠금 처리, 이용제재 시 발생
다음 프로퍼티 포함
reason: 계정 비활성화 사유

필수 보안 조치: 계정이 비활성화된 이유가 hijacking 인 경우 현재 열려있는 세션을 종료하여 사용자 계정 보호
권장 보안 조치: 계정이 비활성화된 이유가 bulk-account인 경우 서비스에서 사용자의 활동을 분석하고 필요한 후속 조치 결정
Schema: https://schemas.openid.net/secevent/risc/event-type/account-disabled
Account Enabled 계정 활성화
카카오계정 휴면 또는 도용 상태에서 복구될 때 발생

권장 보안 조치: 사용자의 카카오 로그인 및 카카오계정 이메일 주소로 계정 복구 기능을 다시 활성화
Schema: https://schemas.openid.net/secevent/risc/event-type/account-enabled
Account Purged 계정 탈퇴

권장 보안 조치: 사용자 계정 삭제 또는 다른 로그인 방법 제공
Schema: https://schemas.openid.net/secevent/risc/event-type/account-purged
Credential Compromise 계정 자격증명 손상
카카오계정 자격증명 탈취 의심 상태(예: 계정 탈취가 의심되는 새로운 환경에서 로그인 성공)

권장 보안 조치: 서비스에서 의심스러운 활동이 있는지 확인하여 필요한 후속 조치 결정
Schema: https://schemas.openid.net/secevent/risc/event-type/credential-compromise
Identifier Changed 계정 식별자 변경
사용자의 이메일 또는 전화번호가 변경되었을 경우 발생

권장 보안 조치: 기존 사용자의 전화번호 또는 이메일을 파기하고, 변경된 전화번호나 이메일로 업데이트
Schema: https://schemas.openid.net/secevent/risc/event-type/identifier-changed
Identifier Recycled 기존 계정 식별자 사용 불가
카카오계정의 이메일 또는 전화번호가 다른 사용자에게 사용돼 이메일 인증 만료(Expired), 유예(Suspended) 상태가 된 경우 발생

권장 보안 조치: 사용자 계정의 이메일 및 전화번호를 더 이상 사용하지 않도록 처리하고, 서비스에서 직접 새로운 이메일 및 전화번호 수집
Schema: https://schemas.openid.net/secevent/risc/event-type/identifier-recycled
Sessions Revoked 계정의 모든 세션 만료
비밀번호 변경 후 기존 기기 로그아웃 처리로 인해 발생

필수 보안 조치: 현재 열려 있는 세션을 종료하여 사용자 계정 보호
Schema: https://schemas.openid.net/secevent/risc/event-type/sessions-revoked
CAEP Assurance Level Change 인증 보안 수준 변경
2차 인증 설정 등 보안 수준 변경 시 발생

권장 보안 조치: 현재 사용자가 서비스 이용에 필요한 인증 보안 수준을 충족하는지 확인 후, 필요에 따라 재인증 등 조치를 거쳐 서비스 제공
Schema: https://schemas.openid.net/secevent/caep/event-type/assurance-level-change
Credential Change 계정 비밀번호 변경
비밀번호 재설정 또는 카카오 인증서 재발급 시 발생

Schema: https://schemas.openid.net/secevent/caep/event-type/credential-change

보안 이벤트 수신

콜백 정보

사용자의 보안 이벤트 발생 시, 보안 이벤트 정보를 서비스의 콜백 URL에 HTTP POST 요청으로 전달합니다. 콜백 요청의 헤더(Header) Content-Typeapplication/secevent+jwt, 바디(Body)는 보안 이벤트 정보가 담긴 SET 값입니다.

아래는 콜백 URL로 전달되는 요청 예시입니다.

POST /kakao/events HTTP/1.1   
Host: callback.example.com   
Content-Type: application/secevent+jwt    
Accept: application/json   

eyJraWQiOiI2NjVhYmVlYzExOGRkZmMyZDNiZjNlMmFkYWU3OT...

서비스는 콜백 URL에 전달된 콜백에 대해 SET 검증성공 또는 실패로 응답해야 합니다.

주의

콜백 요청이 지속적으로 실패하거나 무응답인 경우, 앱의 보안 이벤트 구독 상태가 비활성화되고 보안 이벤트 전달이 중단됩니다. 이 경우, 서비스에서 보안 이벤트 수신 처리에 이상이 없는지 확인 후 다시 보안 이벤트 구독 설정을 해야 합니다.

SET 정보

서비스는 카카오계정의 보안 이벤트 정보가 담긴 SET를 POST 메서드로 전달받습니다. SET은 JWT(JSON Web Token) 형식의 토큰으로, 다음 세 가지 영역으로 구성돼 있습니다.

SET 구성
구분 설명
헤더(Header) SET 규격 정보
페이로드(Payload) 보안 이벤트 정보
서명(Signature) 카카오 인증 서버(KAUTH)가 헤더kid에 해당하는 공개키로 서명한 값

아래는 헤더, 페이로드 영역에 포함되는 필드의 상세 정보입니다.

헤더
Name Type Description
alg String SET에 적용된 암호화 방식, RS256으로 고정
typ String SET의 형식, secevent+jwt으로 고정
kid String SET 암호화 시 사용된 공개키 ID
메타데이터 조회의 SET 암호화 공개키 조회 URI(jwks_uri)에서 확인 가능
페이로드
Name Type Description
iss String SET 발급 기관, https://kauth.kakao.com로 고정
aud String SET를 전달받는 앱의 REST API 키
sub String SET에 해당하는 사용자 회원번호
iat String SET 발급 시간
jti String SET 고유 식별 값
events Event 보안 이벤트 타입 및 상세 정보
Event
Name Type Description
${SCHEMA} JSON 보안 이벤트 타입별 상세 정보
키는 보안 이벤트 타입Schema
값은 보안 이벤트 타입마다 차이가 있으므로 아래 보안 이벤트 상세 정보 참고
보안 이벤트 상세 정보
Event Type Name Type Description
공통 subject Subject 보안 이벤트 상세 정보
OAuth >
User Unlinked
reason String 연결 끊기 사유, 다음 중 하나
ACCOUNT_DELETE: 카카오계정 탈퇴
FORCED_ACCOUNT_DELETE: 장기 휴면 또는 고객센터를 통한 카카오계정 강제 탈퇴
INCOMPLETE_SIGN_UP: 가입 미완료자 탈퇴
UNLINK_FROM_ADMIN: 카카오 관리자로 인한 탈퇴 처리
UNLINK_FROM_APPS: 카카오계정 페이지를 통한 서비스 연결 끊기
REVOKE_ACCOUNT_SERVICE_TERMS: 통합서비스 약관 동의 철회
UNLINK_FROM_SERVICE: 서비스 탈퇴
OAuth >
User Scope Consent,
User Scope Withdraw
scope String 사용자가 동의 또는 동의 철회한 동의 항목
각 동의 항목의 ID를 공백으로 이어 붙인 하나의 문자열
(예: email birthday age_range)
RISC >
Identifier Changed,
Identifier Recycled
new-value String 변경된 전화번호 또는 이메일 값
CAEP >
Assurance Level Change
current_level String 카카오계정 인증 레벨
nist-aal1: 2차 인증 미설정 상태
nist-aal2: 2차 인증 설정 상태
change_direction String 카카오계정 인증 레벨 변경사항
increase: 인증 레벨 상향
decrease: 인증 레벨 하향
previous_level String 변경 전 카카오계정 인증 레벨
nist-aal1: 2차 인증 미설정 상태
nist-aal2: 2차 인증 설정 상태
CAEP >
Credential Change
change_type String 계정 비밀번호 변경 유형
update: 비밀번호 변경 또는 카카오 인증서 재발급
Subject
Event Type Name Type Description
공통 subject_type String 사용자 식별자 타입
iss_sub: 회원번호
phone: 전화번호
email: 이메일
iss String SET 발급 기관
https://kauth.kakao.com로 고정

비고: Identifier Changed, Identifier Recycled 타입 보안 이벤트 정보에는 미포함
sub String SET에 해당하는 사용자 회원번호

비고: Identifier Changed, Identifier Recycled 타입 보안 이벤트 정보에는 미포함
RISC >
Identifier Changed,
Identifier Recycled
phone_number String 변경 또는 사용 불가 처리된 기존 전화번호 값
email String 변경 또는 사용 불가 처리된 기존 이메일 값

SET은 세 영역의 값을 Base64 인코딩(Encoding) 한 후 온점(.)으로 이어 붙인 하나의 문자열로 생성됩니다. 따라서 온점을 기준으로 각 영역을 분리하고, Base64 디코딩(Decoding)하여 내용을 확인할 수 있습니다. 서비스는 SET 검증 후 페이로드 내용을 확인하여 필요한 사용자 계정 보호 조치를 수행할 수 있습니다. 아래는 디코딩된 SET 헤더와 페이로드 예제입니다.

헤더
페이로드
{
    "kid": "665abeec118ddfc2d3bf3e2adae799",
    "typ": "secevent+jwt",
    "alg": "RS256"
}
{
    "iss": "https://kauth.kakao.com",
    "aud": "${REST_API_KEY}",
    "sub": "${USER_ID}",
    "txm": "92a79799-3ae3-4112-8fe2-921c710daa38",
    "iat": 1674702636,
    "jti": "6a1a7a3e-b923-4eb8-886c-cbcbd1621fb0",
    "events": {
        "https://schemas.openid.net/secevent/oauth/event-type/user-linked": {
            "subject": {
                "sub": "1376016924429759243",
                "subject_type": "iss-sub",
                "iss": "https://kauth.kakao.com"
            }
        }
    }
}

SET 검증

서비스는 보안 이벤트 정보에 따른 사용자 계정 보호 조치를 수행하기 전 반드시 SET 내용을 확인하고 검증해야 합니다. 다음 순서로 SET 내용을 확인하고 검증할 수 있습니다.

  1. 온점(.)을 기준으로 헤더, 페이로드, 서명을 분리
  2. 페이로드를 Base64 방식으로 디코딩
  3. 페이로드의 iss 값이 https://kauth.kakao.com와 일치하는지 확인
  4. 페이로드의 aud 값이 서비스 앱의 REST API 키와 일치하는지 확인
  5. 서명 검증

서명 검증은 다음 순서로 진행합니다.

  1. 헤더를 Base64 방식으로 디코딩
  2. OIDC: 공개키 목록 조회하기를 통해 카카오 인증 서버가 서명 시 사용하는 공개키 목록 조회
  3. 공개키 목록에서 헤더의 kid에 해당하는 공개키 값 확인
    • 공개키는 일정 기간 캐싱(Caching)하여 사용할 것을 권장하며, 지나치게 빈번한 요청 시 요청이 차단될 수 있으므로 유의
  4. JWT 서명 검증을 지원하는 라이브러리를 사용해 공개키로 서명 검증
    • 참고: OpenID Foundation, jwt.io
    • 라이브러리를 사용하지 않고 직접 서명 검증 구현 시, RFC7515 규격에 따라 서명 검증 과정 진행 가능

성공 응답

콜백 URL을 통해 SET 수신 서버가 콜백 요청을 전달받아 SET 검증에 성공한 경우, Response Body 없이 HTTP 응답 코드 202 Accepted로 응답해야 합니다. 아래 예제를 참고합니다.

HTTP/1.1 202 Accepted

실패 응답

콜백 URL을 통해 SET 수신 서버에서 콜백 요청을 전달받았으나 SET 검증에 실패한 경우, HTTP 응답코드 400 Bad Request로 응답해야 합니다. 응답 헤더의 Content-Typeapplication/json이어야 하며, 바디에 JSON 형식으로 RFC8935 규격에 따라 에러 코드(err)와 사유(description)를 전달합니다. 아래 예제를 참고합니다.

HTTP/1.1 400 Bad Request 
Content-Type: application/json
{
    "err": "invalid_key",
    "description": "Key ID 12345 has been revoked."
}
실패 응답 에러 코드
Error Code Description
invalid_request 전달된 SET가 JWT 규격에 맞지 않을 경우
invalid_key 전달된 SET를 카카오의 공개키로 복호화 실패 시
invalid_issuer 전달된 SET의 issuer가 카카오가 아닐 경우
invalid_audience 전달된 SET의 aud 값이 서비스 앱ID와 일치하지 않을 경우

테스트

[도구] > [보안 이벤트 테스트]에서 보안 이벤트 테스트 전송이 가능합니다. 해당 기능을 사용해 보안 이벤트 수신 처리가 올바르게 구현되었는지 확인할 수 있습니다.

보안 이벤트 테스트 전송 요청 화면

🅐 App: 테스트 대상 앱 선택 🅑 콜백 URL: 보안 이벤트 설정을 완료한 경우, 설정된 콜백 URL 출력 🅒 카테고리: 보안 이벤트 카테고리 선택, 테스트 시에는 모든 카테고리 선택 가능 🅓 이벤트 타입: 테스트 전송할 보안 이벤트 타입 선택, 테스트 시에는 모든 타입 선택 가능

[발송]을 누르면 페이지 하단에 아래와 같은 테스트 정보가 나타납니다.

보안 이벤트 테스트 전송 요청 정보 화면

🅐 보안 이벤트 요청: 테스트 전송된 요청 전문, 콜백 URL 미설정 시 HostURL 미포함 예시 출력 🅑 보안 이벤트 토큰: 🅐의 요청에 포함된 SET을 디코딩한 값, headerpayload 각각 출력, 디버깅 시 참고