고위험 기능을 위한 연령 보증
일부 권한은 특정 관할권에서 활성화되기 전에 확인된 연령이 필요합니다. 예를 들어 브라질(BR)에서 loot-boxes-paid-cosmetic-only, loot-boxes-paid-gameplay-impacting, targeted-ads, profiling은 verifiedAgeThreshold 18이 필요합니다. 이러한 권한은 기본적으로 비활성화되어 있으며, 연령 요건에 대해 확인된 것으로 간주되는 플랫폼 신호 또는 전용 연령 보증 Challenge(CHALLENGE_SESSION_UPGRADE_BY_AGE_ASSURANCE)를 통해서만 잠금을 해제할 수 있습니다.
이 페이지의 활용 방법
다음 사항을 이해해야 할 때 이 페이지를 사용하세요:
- 플레이어가 이미 연령 게이트를 통과했음에도 권한이 여전히 비활성화된 이유
POST /session/upgrade가 권한을 즉시 활성화하는지 아니면 Challenge를 반환하는지 여부- 임계값을 충족하지만 아직 연령을 확인하지 않은 플레이어를 처리하는 방법
- 원래 임계값 미만의 연령을 주장한 플레이어를 복구하는 방법
확인된 연령 임계값
verifiedAgeThreshold는 단순히 주장하거나 추정된 연령이 아닌 확인된 연령이 필요하다는 것을 의미합니다.
현재 주요 예시:
- 브라질(
BR):loot-boxes-paid-cosmetic-only,loot-boxes-paid-gameplay-impacting,targeted-ads,profiling은 확인된 연령18이 필요하고,direct-marketing은 확인된 연령12가 필요합니다
verifiedAgeThreshold가 있는 권한은:
managedBy: GUARDIAN이 될 수 없음- 플레이어가 충분히 나이가 들었지만 아직 확인이 필요한 경우
managedBy: PLAYER - 플레이어가 임계값 미만인 경우
managedBy: PROHIBITED
현재 이 내용은 위 목록의 브라질 권한에 적용됩니다. 추가 관할권이 확인된 연령 요건을 추가할 경우 동일한 권한 모델이 적용됩니다。
권한 상태 로직
권한에 verifiedAgeThreshold가 있는 경우 Permission 객체에 해당 필드가 포함됩니다:
{
"name": "loot-boxes-paid-gameplay-impacting",
"enabled": false,
"managedBy": "PLAYER",
"verifiedAgeThreshold": 18
}
| 임계값 대비 플레이어 연령 | 연령 확인 여부 | managedBy | enabled |
|---|---|---|---|
| 임계값 미만 | 해당 없음 | PROHIBITED | false |
| 임계값 이상 | 아니오 | PLAYER | false |
| 임계값 이상 | 예, 확인된 플랫폼 신호를 통해 | PLAYER | true |
| 임계값 이상 | 예, 연령 보증을 통해 | PLAYER | true |
임계값 권한은 managedBy: GUARDIAN이 될 수 없습니다. 보호자 동의로는 이를 잠금 해제할 수 없습니다.
세션의 ageVerification
확인된 플랫폼 신호가 처리되거나 연령 보증 Challenge가 완료되면 세션에 ageVerification 객체가 저장됩니다:
{
"ageVerification": {
"verifiedAge": 18,
"platformName": "apple-ios",
"declarationType": "governmentIDChecked",
"verifiedAt": "2026-03-14T00:00:00Z"
}
}
이 확인은 재사용 가능합니다. 세션에 저장되면 이후 동일하거나 낮은 임계값을 가진 권한에 대한 POST /session/upgrade 호출은 일반적으로 새 Challenge 없이 충족될 수 있습니다.
세션 업그레이드 흐름
POST /session/upgrade는 플레이어가 고위험 권한을 즉시 받을 수 있는지 아니면 먼저 확인이 필요한지를 결정하는 엔드포인트입니다.
세션 업그레이드 API
관련 요청 필드:
| 필드 | 타입 | 설명 |
|---|---|---|
platformAgeSignal | PlatformAgeSignal | 임계값을 즉시 충족할 수 있는 플랫폼 신호 |
options | object | 연령 보증 경험으로 전달되는 옵션 |
options.facialAgeEstimation.passIfOver | integer | 얼굴 연령 추정이 통과해야 하는 최소 연령 |
options.facialAgeEstimation.failIfUnder | integer | 얼굴 연령 추정이 실패해야 하는 최대 연령 |
options.redirectUrl | string | Challenge 완료 후 리디렉션 대상 |
요청 예시 (확인된 플랫폼 신호가 권한을 충족하는 경우):
POST /api/v1/session/upgrade
{
"sessionId": "608616da-4fd2-4742-82bf-ec1d4ffd8187",
"requestedPermissions": [
{ "name": "loot-boxes-paid-gameplay-impacting" }
],
"platformAgeSignal": {
"name": "apple-ios",
"ageLow": 18,
"ageHigh": 25,
"declarationType": "governmentIDChecked"
}
}
{
"session": {
"sessionId": "608616da-4fd2-4742-82bf-ec1d4ffd8187",
"permissions": [
{
"name": "loot-boxes-paid-gameplay-impacting",
"enabled": true,
"managedBy": "PLAYER",
"verifiedAgeThreshold": 18
}
],
"ageVerification": {
"verifiedAge": 18,
"platformName": "apple-ios",
"declarationType": "governmentIDChecked",
"verifiedAt": "2026-03-14T00:00:00Z"
}
}
}
요청 예시 (플레이어가 임계값을 충족하지만 아직 연령 보증이 필요한 경우):
POST /api/v1/session/upgrade
{
"sessionId": "608616da-4fd2-4742-82bf-ec1d4ffd8187",
"requestedPermissions": [
{ "name": "loot-boxes-paid-gameplay-impacting" }
],
"options": {
"redirectUrl": "https://mygame.com/callback"
}
}
{
"session": {
"sessionId": "608616da-4fd2-4742-82bf-ec1d4ffd8187",
"permissions": [
{
"name": "loot-boxes-paid-gameplay-impacting",
"enabled": false,
"managedBy": "PLAYER",
"verifiedAgeThreshold": 18
}
]
},
"challenge": {
"challengeId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"type": "CHALLENGE_SESSION_UPGRADE_BY_AGE_ASSURANCE",
"url": "https://family.k-id.com/session/upgrade/age-assurance?token=..."
}
}
결과 예시 (플레이어가 임계값 미만인 경우):
{
"session": {
"sessionId": "608616da-4fd2-4742-82bf-ec1d4ffd8187",
"permissions": [
{
"name": "loot-boxes-paid-gameplay-impacting",
"enabled": false,
"managedBy": "PROHIBITED",
"verifiedAgeThreshold": 18
}
]
}
}
이 경우 플레이어가 해당 권한을 받을 만큼 나이가 들지 않았기 때문에 Challenge가 반환되지 않습니다.
주요 동작:
- 요청된 모든 권한은
verifiedAgeThreshold가 있거나 없어야 합니다 - 플레이어가 임계값 미만인 경우 권한은
PROHIBITED로 유지되고 Challenge가 발급되지 않습니다 - 확인된 플랫폼 신호는 요청된 일부 또는 모든 권한을 즉시 충족할 수 있습니다
- 세션의 기존
ageVerification도 요청을 충족할 수 있습니다 - 해결되지 않은 나머지 권한만 연령 보증 Challenge로 전환됩니다
Challenge 결과 처리
Challenge URL은 https://family.k-id.com/session/upgrade/age-assurance?token=...을 가리킵니다.
플레이어가 이 URL을 열면:
- 토큰이 파싱되고 유효성이 검사됩니다.
- Challenge가 이미 해결된 경우 플레이어는 완료 페이지로 리디렉션됩니다.
- 아직 대기 중인 경우 k-ID의 연령 확인 방법(예: 얼굴 연령 추정 또는 ID 문서 스캔)이 포함된 확인 iframe이 표시됩니다.
- 완료 시 결과가 통합으로 다시 전달됩니다.
결과를 받는 세 가지 방법이 있습니다:
옵션 1: postMessage 수신
iframe 또는 webview 통합의 경우, family portal이 부모 창에 Challenge.StateChange 메시지를 게시합니다:
{
"eventType": "Challenge.StateChange",
"data": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"productId": "your-product-id",
"status": "PASS"
}
}
DOM postMessage 이벤트는 UI를 업데이트하는 데 유용하지만 권위 있는 소스가 아닙니다. 서버 측 로직에는 웹훅 또는 폴링 엔드포인트를 사용하세요。
옵션 2: GET /challenge/get-status 폴링
GET /api/v1/challenge/get-status?challengeId=a1b2c3d4-e5f6-7890-abcd-ef1234567890
가능한 상태는 PASS, FAIL, PENDING, IN_PROGRESS입니다.
옵션 3: Challenge.StateChange 웹훅 수신
k-ID는 Challenge 상태가 변경될 때마다 구성된 엔드포인트로 Challenge.StateChange 웹훅 이벤트를 게시합니다:
{
"eventType": "Challenge.StateChange",
"data": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"productId": 11472,
"status": "PASS",
"sessionId": "608616da-4fd2-4742-82bf-ec1d4ffd8187"
}
}
| 필드 | 설명 |
|---|---|
data.id | POST /session/upgrade가 반환한 challengeId |
data.status | PASS, FAIL 또는 IN_PROGRESS |
data.sessionId | PASS 시 존재: 새로 고쳐진 세션을 가져오는 데 사용 |
웹훅은 실시간으로 전달되고 폴링이 필요 없기 때문에 서버 측 처리에 권장되는 방법입니다. 전체 필드 참조 및 상태 수명 주기는 Challenge.StateChange를 참조하세요.
결과 이후
PASS이후,GET /session/get을 가져와 새로 고쳐진 권한을 사용하세요. 임계값 권한이 이제 활성화되고 세션에ageVerification이 포함되어야 합니다.FAIL이후, 권한은 비활성화 상태로 유지됩니다. 플레이어는 나중에POST /session/upgrade를 다시 호출하여 재시도할 수 있습니다.
임계값 미만의 연령을 입력한 플레이어를 위한 복구 흐름
때로는 플레이어가 고위험 권한의 임계값 미만으로 주장된 연령을 입력하여 PROHIBITED 권한을 갖게 되는 경우가 있습니다. 이 경우 세션에 이미 플레이어가 해당 기능을 사용하기에 너무 어리다고 표시되어 있기 때문에 일반적인 session/upgrade 흐름으로는 문제를 해결할 수 없습니다.
이 복구 흐름은 다음을 위한 것입니다:
- 플레이어 관리 세션
- 아직 연결된 승인자가 없는 보호자 관리 세션
세션이 보호자 관리이고 이미 승인자가 연결된 경우에는 적합하지 않습니다.
복구 단계
- 플레이어를 AgeKit+의 연령 이의 신청으로 안내합니다. 적절한
jurisdiction및criteria와 함께POST /age-verification/perform-age-appeal를 호출합니다. 반환된 URL을 iframe 또는 webview에 표시하여 플레이어가 연령 확인을 완료할 수 있도록 합니다. 아직 세션을 무효화하지 마세요: 이의 신청이 실패하면 플레이어는 기존 세션을 유지하고 VPC를 다시 거칠 필요가 없습니다. - 연령 이의 신청 결과를 처리합니다. DOM 이벤트, 웹훅 또는
GET /age-verification/get-status를 통해 결과를 수신합니다.- 성공 시: 이의 신청은 플레이어의 확인된 연령을 증명하는
verificationId를 생성합니다. - 실패 시: 기능은 금지된 상태로 유지됩니다. 플레이어는 원래 주장된 연령으로 유지되고 기존 세션이 보존됩니다.
- 성공 시: 이의 신청은 플레이어의 확인된 연령을 증명하는
- 세션을 무효화합니다. 성공적인 이의 신청 후, 플레이어가 새로 시작할 수 있도록 서버 측에서
sessionId를 삭제합니다. 세션 무효화 엔드포인트는 향후 릴리스에서 계획되어 있습니다. 지금은 클라이언트 측에서 세션을 제거하는 것으로 충분합니다. - k-ID 신호로 연령 게이트 흐름을 다시 시작합니다. 이의 신청의
verificationId를k-id플랫폼 신호로 전송합니다.
POST /api/v1/age-gate/check
{
"jurisdiction": "BR",
"platformAgeSignal": {
"name": "k-id",
"verificationId": "<verificationId from age appeal>"
}
}
k-ID는 verificationId에서 확인된 연령을 확인합니다. 확인된 연령이 verifiedAgeThreshold를 충족하거나 초과하면 고위험 권한이 활성화된 상태로 세션이 생성됩니다.
순차적 권한 업그레이드
각 임계값 권한은 독립적으로 추적됩니다:
- 하나의 권한을 업그레이드해도 다른 권한이 자동으로 업그레이드되지 않습니다
- 각 권한은 여전히
POST /session/upgrade를 통해 요청되어야 합니다 - 세션에
ageVerification이 있으면 동일하거나 낮은 임계값을 가진 이후 권한은 종종 다른 Challenge 없이 충족될 수 있습니다