폐기 및 상태
핵심 요약
서명된 사용권이 있어도 라이선스가 영구 유효한 것은 아닙니다. 서버는 보호 요청마다 현재 상태를 확인해 정지·회수된 권한을 거부합니다.
사고 대응 시 상태 확인 → 승인된 변경 → 기존 권한의 요청 거부 확인 순으로 검증하세요.
규칙
라이브 라이선스 행은 가드된 모든 호출에서 재조회됩니다. 아직 유효한 entitlement 서명도 행을 무시하지 못합니다: 라이선스를 폐기하면 다음 capability/execute/status 호출이 실패합니다 — 120초 토큰 TTL이 아닌 검사 자체로만 경계됩니다.
상태 값 및 효과
licenses.status는 active · revoked · suspended · expired · (그 외 → INVALID_STATUS)를 받습니다.
| 상태 | 활성화 | 가드된 호출 (capability/execute/status) | 공개 검증 판정 |
|---|---|---|---|
active | 허용 | 허용 | valid:true, code:OK |
revoked | 403 REVOKED | 거부 | code:REVOKED |
suspended | 403 SUSPENDED | 거부 | code:SUSPENDED |
expired | 403 EXPIRED | 거부 | code:EXPIRED |
| 알 수 없는 값 | 403 INVALID_STATUS | 거부(SDK는 REVOKED로 매핑 — fail closed) | code:INVALID_STATUS |
expires_at 경과 | 만료로 취급 | 거부 | code:EXPIRED |
execute/capability 가드 경로에서 INVALID_STATUS가 아닌 게이트 판정은 403 FORBIDDEN으로 축소됩니다 — 구체적 코드는 license_blocked 보안 이벤트에만 남습니다. /activate는 게이트 판정 코드를 그대로 반환합니다 (매트릭스 §2 각주).
폐기 / 정지 / 복원 방법
http
PATCH /api/v1/licenses/:id (셀러 소유자)
{ "status": "revoked" } // 또는 "suspended", "active" (복원)
{ "expires_at": "…" } // 만료 강제도 가능1
2
3
2
3
레거시 플레인: POST /licenses가 발급(lic_… id + NG-… 키); PATCH /licenses/:id가 status/expires_at을 변경합니다.
상태 확인
- 공개(무인증, 양쪽 백엔드):
POST /api/v1/licenses/verify{key[, product_id, device_id]}→{valid, code, status, product_id, product_name, expires_at, max_devices, activated_devices, device_registered, checked_at}. 조회 전용 — 슬롯을 소비하지 않습니다.yp license verify <key>와 게이트웨이 도구yetdapay_license_verify로도 노출됩니다. - Entitled 클라이언트(Worker PoP):
GET /api/v1/licenses/status(entitlement + DPoP) →{license:{product_id, product_name, status, expires_at, max_devices, bound_devices, activated_devices, features, entitlement_exp}}. - 셀러:
GET /api/v1/licenses(스코프 목록 — 키 미노출),GET /licenses/:id/bindings,GET /licenses/:id/usage,GET /security-events?lic_id=— 모두 게이트웨이의yetdapay_license_*도구 또는 셀러 콘솔로 도달 가능합니다.
인시던트 자세
폐기는 유출/남용된 라이선스의 주요 인시던트 레버입니다 — 해당 lic_id의 security-events 리뷰로 후속하세요(리플레이 시도, jkt 이상, license_blocked 행). 인시던트 대응 참조.