활성화
핵심 요약
활성화는 라이선스 키와 기기 공개키를 연결하고 서버가 허용하면 단기 사용권을 발급합니다. 단순 키 조회는 기기 등록이 아닙니다.
아래 요청 예제로 활성화한 뒤 응답 상태와 기기 수 제한을 확인하세요.
활성화는 라이선스 키 + 디바이스 공개 키를 바인딩된 디바이스 슬롯과 단기 entitlement로 변환합니다.
요청/응답 (모든 경로에서 동일한 body)
http
POST {activatePath}
{ "key": "NG-XXXX-XXXX", "product_id": "prod_…", "public_jwk": { … } }1
2
2
json
{ "entitlement": "<jws>", "expires_in": 120, "features": ["…"] }1
백엔드 간 유일한 차이는 라우트입니다.
활성화 경로
| 표면 | 라우트 | 모델 |
|---|---|---|
be-cloudflare (PoP) | POST /api/v1/licenses/activate | public_jwk on-curve 검증 → 라이선스 게이트 검사 → 원자적 license_bindings 슬롯(UNIQUE(lic_id,jkt), count < max_devices) → entitlement |
@yetdapay/license-server (BYOS) | POST /api/license/activate (DEFAULT_ACTIVATE_PATH) | 동일 body/응답; PoC/Nuxt 스타일 자체 호스팅 |
| SDK worker 프리셋 | POST /api/v1/licenses/activate (WORKER_ACTIVATE_PATH, createWorkerConfig()) | 동일 wire 형식, Worker 라우트 |
Axum be/ (레거시만) | POST /api/v1/licenses/verify + POST /licenses/:id/activations | activations_json 표시 레코드 — PoP 없음, entitlement 미발급 |
서버가 검사하는 것
public_jwk— 정규화되고 on-curve 검증됨(invalid public_jwk→400).- 라이선스 게이트 — 키 존재,
product_id가 라이브 라이선스 행과 일치 (드리프트 → 401/403 PRODUCT_MISMATCH), 상태active, 미만료. - 디바이스 슬롯 —
countBindings(lic_id) < max_devices; 바인딩(lic_id, jkt)은 유일 — 동일 디바이스 재활성화는 멱등, 제한 초과 새 디바이스 →DEVICE_LIMIT.
오류 코드 (활성화)
| 실패 | Worker | SDK |
|---|---|---|
| 잘못된 body / 나쁜 JWK | 400 VALIDATION | 400 VALIDATION / 400 INVALID_PUBLIC_JWK |
| 알 수 없는 키 | 403 NOT_FOUND ("license not activatable") | 404 NOT_FOUND |
| 상품 불일치 | 403 PRODUCT_MISMATCH | 403 PRODUCT_MISMATCH |
| revoked/suspended/expired | 403 동일 코드 | 403 동일 코드 |
알 수 없는 status | 403 INVALID_STATUS | 403 REVOKED (fail closed) |
| 디바이스 제한 | 403 DEVICE_LIMIT | 403 DEVICE_LIMIT |
403/404 NOT_FOUND 델타와 INVALID_STATUS→REVOKED fail-closed 델타는 문서화된 의도적 차이입니다 — 계약 매트릭스 §2 참조.
레거시 경로 (PoP 없음)
POST /api/v1/licenses/verify(공개, 양쪽 백엔드)는 조회 전용 판정입니다 — {valid, code, status, product_id, product_name, expires_at, max_devices, activated_devices, device_registered, checked_at}, 코드는 OK|NOT_FOUND|PRODUCT_MISMATCH|REVOKED|SUSPENDED|EXPIRED|INVALID_STATUS — 그리고 슬롯을 소비하지 않습니다. POST /licenses/:id/activations / DELETE /licenses/:id/activations/:device(셀러 소유자)는 레거시 device_id 레코드를 표시 전용으로 관리합니다.