Capability
핵심 요약
Capability는 특정 유료 기능을 한 번 실행하도록 허용하는 단기·일회용 권한입니다. 서버가 원자적으로 소비하고 재사용을 거부해야 합니다.
아래 흐름에서 사용권·기기 증명 → Capability 발급 → 서버 실행 → 재사용 거부를 확인하세요.
Capability는 단일 기능에 대한 60초, 일회성 실행 부여입니다 — "라이선스됨"을 "이 유료 연산을 정확히 한 번, 서버 계량으로 실행 가능"으로 바꾸는 메커니즘입니다.
흐름
http
POST /api/v1/licenses/capability (entitlement + DPoP)
{ "feature": "premium_convert" }
→ { "cap_id": "…", "feature": "premium_convert", "exp": … }1
2
3
2
3
http
POST /api/v1/licenses/execute (entitlement + DPoP + capability)
{ "feature": "premium_convert", "input": …, "cap_id": "…" }
→ { "result": … }1
2
3
2
3
Worker에서 execute는:
- 전체 가드 체인을 재실행합니다(entitlement → 라이브 라이선스 행 → DPoP →
jkt→jti→ body 해시). - Capability를 검증합니다(존재, 기능 일치, 미소비, 미만료).
- 원자적으로 소비합니다(
UPDATE … WHERE consumed=0). - 내장
premium_convert만 실행합니다 — Worker는 정확히 하나의 데모 등급 유료 함수를 실행합니다; BYOS 셀러는@yetdapay/license-server의issueCapability()/capability 저장소를 통해 동일한 일회 소비 규칙으로 자체 핸들러를 실행합니다. license_usage행을 씁니다(최선 노력 — 이것이 미터링 표면; BYOS 실행은 DevPay에 보이지 않음).
재사용 → 409 CAPABILITY_CONSUMED. 알 수 없거나 불일치하는 capability → Worker는 403 FORBIDDEN("invalid capability"), SDK는 403 CAPABILITY_INVALID — 문서화된 델타(둘 다 403; 매트릭스 §2).
왜 일회성인가
Capability는 인가를 실행 횟수에 묶습니다: 유효한 entitlement를 가진 클라이언트도 유료 연산을 발급된 capability당 한 번만 실행할 수 있습니다 — 미터링은 바이어가 패치할 수 있는 클라이언트 카운터가 아닌 원장 측입니다.
TTL
| 객체 | TTL |
|---|---|
| capability | 60 s |
| entitlement | 120 s |
증명 iat 윈도우 | ±60 s |
소비된 jti 논스 | 600 s (플래그 켜지면 cron으로 정리) |
미터링 경계
license_usage 행은 DevPay 호스티드 /licenses/execute에서만 나옵니다. 셀러의 BYOS 서버는 자체 사용량을 로컬에 기록합니다 — DevPay는 그 실행을 보지 못하고, 사용량 보고 엔드포인트도 존재하지 않습니다 (known-limitations §3.5, PARTIAL).