Capability
Quick summary
A capability is a short-lived, single-use permission for one protected feature execution. The server must consume it atomically and reject replay.
Follow the request sequence below: entitlement + device proof → capability → server-side execution → replay rejection.
A capability is a 60-second, one-time execution grant for a single feature — the mechanism that turns "licensed" into "may run this paid operation exactly once, server-metered".
Flow
POST /api/v1/licenses/capability (entitlement + DPoP)
{ "feature": "premium_convert" }
→ { "cap_id": "…", "feature": "premium_convert", "exp": … }2
3
POST /api/v1/licenses/execute (entitlement + DPoP + capability)
{ "feature": "premium_convert", "input": …, "cap_id": "…" }
→ { "result": … }2
3
On the Worker, execute:
- Re-runs the full guard chain (entitlement → live license row → DPoP →
jkt→jti→ body hash). - Validates the capability (exists, feature matches, unconsumed, unexpired).
- Atomically consumes it (
UPDATE … WHERE consumed=0). - Runs the built-in
premium_convertonly — the Worker executes exactly one demo-grade paid function; BYOS sellers run their own handlers under the same consume-once rule via@yetdapay/license-server'sissueCapability()/capability store. - Writes a
license_usagerow (best-effort — this is the metering surface; BYOS executions are invisible to DevPay).
Reuse → 409 CAPABILITY_CONSUMED. Unknown/mismatched capability → 403 FORBIDDEN ("invalid capability") on the Worker vs 403 CAPABILITY_INVALID on the SDK — a documented delta (both are 403; matrix §2).
Why one-time
The capability binds authorization to execution count: a client holding a valid entitlement can still only run paid operations once per issued capability — metering is ledger-side, not a client counter the buyer can patch.
TTLs
| Object | TTL |
|---|---|
| capability | 60 s |
| entitlement | 120 s |
proof iat window | ±60 s |
consumed jti nonces | 600 s (pruned by cron when the flag is on) |
Metering boundary
license_usage rows come only from DevPay-hosted /licenses/execute. A seller's BYOS server records its own usage locally — DevPay does not see those executions, and no usage-reporting endpoint exists (known-limitations §3.5, PARTIAL).