### `wai.video.keys`: the proxy form, and a signing proxy in front of any licence server

- **The extension** ([key-release](extensions/key-release.md)) adds form 2 of the
  `wai.video.keys` receipt, signed by a proxy in front of a licence server for every licence
  request it answers, a release or a refusal, under a domain of its own; form 1 keeps its bytes
  and its identity. A receipt names each key's **scheme** (ISO/IEC 23001-7's `cenc`, `cbc1`,
  `cens` and `cbcs`; the HLS methods `AES-128`, `SAMPLE-AES` and `AES-256-GCM` of
  `draft-pantos-hls-rfc8216bis-22` §4.4.4.4), the **key delivery** (an HLS key file, W3C Clear
  Key, or a content protection system by its DASH-IF system ID), which deliveries carry which
  schemes (§3.3), and the SHA-256 of the **CPIX document** the keys came in (DASH-IF CPIX 2.3,
  ETSI TS 103 799).
- **Records**: the key holder's commitment list `WKL1`, derived from the CPIX key material
  (§4.4: each key's KID, scheme, period and commitment), so the proxy copies every `key_commit`
  and holds no key; the entitlement `WKE1`, signed by the operator's entitlement authority and
  bound to a key the viewer's device holds; the device's proof over each request (§6.1, SHA-256
  and Ed25519, which a browser computes with the Web Cryptography API); and the release ticket
  `WKT1` (§9.3), with which a key server redeems a key delivered in the clear once, so the proxy
  never relays one.
- **The decision** (§7.2) is a pure function of those signed inputs, the proxy's clock and its
  earlier receipts, checked in order: an entitlement that does not hold, a stale request, a
  replay, an unknown key, the wrong class, an entitlement not yet valid or ended, a key period
  the entitlement does not meet (key rotation, §7.4), an offline licence the entitlement does
  not allow, and a renewal of no licence, past its count or after the licence lapsed. An offline
  licence never outlives its entitlement (§7.3). A refused request is never forwarded, and a
  key is released by the licence server's 2xx answer or by a ticket, never by the proxy's word
  (§8.4 rule 8).
- **The reference** is the `key_release` module of `wai-rs` (feature `key_release`), with its
  own CPIX reader, which refuses a document type declaration and reads no encrypted key; the
  corpus is [`live-conformance/keys/`](live-conformance/keys/) (releases over each delivery,
  every decision, an expired entitlement, rotation over three periods, offline licences and
  renewals, a licence server that refused, and negative controls giving every reason of §11),
  and its second implementation is `live-conformance/key_release_verify.py`.
- **The service** is `wai/wai-key-proxy`: the proxy, which appends each receipt to a durable,
  single-writer log before it answers, reads it back on a restart, and orders a replay that
  arrives while the first request is being forwarded after it; the key server; and tools to
  derive a list from a CPIX document, issue an entitlement, sign a request and verify a log.
  Its tests run all of it on loopback against a fixture licence server.

