# live-conformance/age — age assurance The corpus of [`extensions/age-assurance.md`](../../extensions/age-assurance.md) §12, in one file, `vectors.json`: - `principals`: each Ed25519 key, by name (informative); - `issuer_keys`: the three issuer keys of the policies, each its `source`, `issuer`, `threshold` and `key` (RFC 9578 §6.5's SubjectPublicKeyInfo, hexadecimal), informative; - `rfc9578_a2_vector1`: RFC 9578 Appendix A.2's first test vector, as published: `pkI`, `token_challenge`, the client's `nonce`, its `blind` *r* and its PSS `salt`, the `token_request` and `token_response` of its issuance, and the `token`, in hexadecimal. A conforming verifier finds that the token's `challenge_digest` is the SHA-256 of `token_challenge`, its `token_key_id` the SHA-256 of `pkI`, and its authenticator *s* a valid RSASSA-PSS signature under `pkI` (RFC 9578 §6.4); and that the issuance holds (§6.1 to §6.3 there, RFC 9474 §4.2 to §4.4): the request's blinded message is (*s*·*r*)^e mod *n*, and the response *s*·*r* mod *n*. A client of the issuance protocol reproduces `token_request` and `token` from the others; - `admission_logs`: admission logs by name, each a list of admissions, `t` (room-clock microseconds), `challenges` (the TokenChallenges the relay sent that session, hexadecimal) and `token` (hexadecimal); - `cases`: each a `name`, an `about`, a `kind` (one of §9.1's), its inputs, and `expect`, what a verifier gives it. Every record is a JSON text (§2). A room's records are hexadecimal: a `descriptor`, `grants` and `chains` (each chain a list of `WEV1` records), and `key_log` (`null` throughout), as the live-rooms corpus gives them. **Cases.** By `kind`: - `ratings`: `claims`, rating claims. `expect`: `accept` with `claims`, each its `link`, `signer`, `subject` (the subject's `type`), `age` and `derived` (1 for a claim with inputs, 0 otherwise); or `refuse` at `["claim", i]`. - `admission`: a room `descriptor`, an age `policy`, the session's `challenges`, the nonces `redeemed`, a `token`, the age `required` and the binding's `origin`: `null` over MOQT, where a challenge's `origin_info` is the room's scope of live-rooms §10.4, or the service's server name over HTTP (§5.6), where it is RFC 9577's list of server names. `expect`: `accept` with the `issuer`, the `threshold` and the `key_id` the token admits under; or `refuse` at `["policy"]` or `["token"]`. - `serving`: a room `descriptor`, a `track` of it (`namespace`, a list of its fields, and `name`), `claims`, and `requests`, each a `threshold`, a `group` and `held`, the indexes of the claims the relay holds when it serves the request, and, for a session that presented a proof of a room key (§5.5), its `service`: the `proof` (hexadecimal) and the `challenge` and `context` the relay holds for the session. `expect`: `accept` with the `track`'s digest and, for each request, the group's `age` and its `outcome`, `serve` (with `service` `true` for the room's own service) or `refuse` with the `reason`; or `refuse` at `["claim", i]`. - `predicate`: a sink's `anchor` (each key's `issuer`, `threshold` and `key`), its `credentials` (tokens, hexadecimal), the `claims` it holds, and `objects`, each a position: a `content_hash`, a `track` digest and a `group`, any of them `null`. `expect`: `accept` with the sink's `state` and, for each object, its `age` and `verdict`, `present` or `withhold`. - `receipt`: a room `descriptor`, an age `policy`, a `receipt`, and `admissions`: the name of an admission log, or `null` for none. `expect`: `accept` with the receipt's `link` and its `cells` (each `window`, `issuer`, `threshold`, `admitted` and `suppressed`); or `refuse` at `["policy"]`, `["admission", i]` or `["receipt"]`. - `room`: a room. `expect`: `accept` with the room's own outcome (`room_outcome`, `accept` or `gap`), `meets_profile` (1 or 0), each grant's `thresholds` in the order given, and the `minor_grants` that took effect, each a grant digest in the merged order; or `refuse` at `["room", …]` with the room verifier's own place (`["room", "record", c, i]` for record `i` of chain `c`), `["grant", i]` or `["record", c, i]`. A verifier that reaches another outcome, reason, place or statement does not conform. **Provenance.** Generated here: `wai_age_assurance_vectors gen` writes `vectors.json` from records authored in code, from fixed seeds. Every Ed25519 key is SHA-256 of a fixed label; every time is a constant (the rooms' `t0` is 2026-10-21T00:00:00Z); every content hash, token nonce, redemption context and RSASSA-PSS salt is SHA-256 output of a fixed label; and Ed25519 signing is deterministic, so the file is the same bytes on every machine. The issuer keys are published test keys whose private keys are published with them: RFC 7517 Appendix A.2's RSA key (threshold 13), RFC 9500 §2.1's `testRSA2048` (16) and RFC 9578 Appendix A.2's issuer key (18), each written as RFC 9578 §6.5's SubjectPublicKeyInfo; the generator signs each token's input with the key directly, the signature the blind protocol would also yield. `rfc9578_a2_vector1` is that RFC's vector as printed. The challenges over MOQT carry the room's scope of live-rooms §10.4, and the refused ones the scopes of the revision before it, or a scope broken one way; those over HTTP carry `room.example`, the corpus's service. The rating schemes, their values and the issuers are `.example` names (RFC 2606) and a `tag:` URI written for the corpus: no scheme here is any classification body's, and nothing in the corpus states what any content deserves. No recorded data. ``` python3 -I ../age_assurance_verify.py . ```