WAI Extension: Cache Metadata
Mirrored from the canonical text at commit c5e7133e ().
Status: Draft. Registers no capability and no record. It is the form in which the cache rules of http-delivery §9 are handed to a cache another party runs, an access network’s edge cache among them, in the metadata that delegation already uses: a CDNI metadata configuration (RFC 8006) for the paths WAI serves, in a form of RFC 8006’s objects alone and in a form that adds the cache-control and compression objects of the open-caching configuration interface (§4), and the capability advertisement (RFC 8008) by which such a cache says what it can enforce and where (§6). A writer renders the configuration; a reader holds one to WAI’s rules exactly and refuses it, with one reason, where it states anything else: a lifetime that overrides the origin’s, a range rule dropped, compression, a cache key that is not the path, a path of WAI’s that an earlier pattern takes (§5). A configuration is an instruction and evidence of nothing. A cache is not trusted for content: a sink holds every byte it is served to the publisher’s signed receipts, whatever the cache was told (jwp-receipts §3; cache-authority §6), and what a cache served is on the signed records other texts define (§7). The reference implementation is the
http_binding::cdnimodule ofwai-rs(featurehttp); the corpus iscache-conformance/cdni/, and its second implementation iscache-conformance/cdni_verify.py. Keywords MUST, MUST NOT, SHOULD, MAY are RFC 2119/8174.Texts read for this revision: the WAI texts this one cites; RFC 8006 §3.3, §4.1, §4.2.1, §4.2.2.2, §4.2.6, §4.3.1 to §4.3.3, §4.3.8, §6.5 to §6.7 and §7.3; RFC 8008 §5.1 to §5.4, §5.7 and Appendix B; RFC 9388 §1 and §2;
draft-ietf-cdni-cache-control-metadata-06§3;draft-ietf-cdni-edge-control-metadata-13§4. The open-caching configuration interface is published by the Streaming Video Technology Alliance as a set of documents listed on its site; their text was not retrievable without an account when this revision was written and was not read. The two drafts above are the form in which that interface’s cache-control and compression objects were brought to the IETF, and this text follows the drafts. A clause number of one of them in this text is that text’s.
1. Scope
In scope: the paths a configuration covers and the rule each takes (§4.1); the configuration document and the objects each path carries, in two forms (§4.2 to §4.5); how a reader holds a configuration to those rules (§5); a cache’s capability advertisement, its footprint, and whether it supports a configuration in a region (§6); and which of a cache’s roles and records this text relies on (§7).
Out of scope: the metadata interface itself (how a configuration is retrieved, RFC 8006 §6);
request routing; access control metadata (location, time and protocol lists, authorisation),
which this revision’s form does not carry; a configuration for paths that are not WAI’s; purge
and pre-positioning; and whether a cache does what it was told, which
cache-conformance/ tests against a running cache and a sink never
relies on.
Relationship to the core spec: this text defines no capability, no payload format and no record (SPEC §5). It signs nothing. It restates no rule: the rules are http-delivery §9’s, and this is one way of writing them down for a cache.
2. Terms
- Cache: an HTTP cache under http-delivery §9, run by a party other than the publisher. Upstream: the party that delegates delivery to it and writes its configuration. In CDNI’s terms the cache is the downstream CDN and the upstream the upstream CDN (RFC 8006 §1).
- Configuration: a
HostIndex(RFC 8006 §4.1.1) as §4.2 writes it. Class: one of the ten kinds of path of §4.1. - Object, in “a class’s objects”: a
GenericMetadataobject (RFC 8006 §4.1.7). Its type is itsgeneric-metadata-type, compared without regard to case, as RFC 8006 §4.1.7 says. - Form:
cdnioropen-caching(§4.3). - Region: a region code of rung-price §2, in its capitals.
- Advertisement: a capability advertisement of RFC 8008 §5.
3. What a configuration is
- An instruction, not evidence. Nothing a sink presents depends on a configuration, on an
advertisement, or on a cache having obeyed either. A sink verifies an object under its object
receipt and its group receipt (jwp-receipts §3),
delivered-verifiedover the bytes it received, whoever sent them, and refuses bytes that fail; a head proof, a receipt file, a playlist receipt and a parameter set are each held to a digest the sink already has (http-delivery §6, §8.1, §8.6, §8.5). A cache that breaks a rule of §9 costs its clients a refused response and a fetch elsewhere. It cannot make them present other bytes. - No new record. What a cache served is already on signed records (§7). A configuration is signed by no one and adds none.
- Exact, or refused. RFC 8006 lets a cache apply defaults where a configuration is silent, and the open-caching objects let an upstream override the origin’s headers. A WAI configuration states every rule of §9 for every class and nothing that departs from them, and a reader refuses one that does (§5). A configuration that is refused is not WAI’s, whatever else it is.
- Mandatory to enforce. Every object of a configuration is marked
mandatory-to-enforce. RFC 8006 §6.6 then requires a cache that does not understand an object, or cannot do what it says, to serve no request it applies to. The rules RFC 8006 has no object for travel in one object of WAI’s own (§4.4), so a cache that does not know it serves nothing under it, and the upstream sees that in the cache’s advertisement before it delegates (§6.3).
4. The configuration
4.1 The classes
A configuration covers ten classes of path. Each is one PathMatch (RFC 8006 §4.1.4) whose
pattern is matched case-sensitively, and they are written in this order:
| class | pattern | what is served there | freshness |
|---|---|---|---|
index | *.wai.receipts | a receipt index (http-delivery §8.2) | revalidate |
head-proof | *.wai.hp | a head proof (http-delivery §6.2) | origin |
object | *.wai | an object under its name (http-delivery §5.2) | origin |
manifest-store | *.c2pa | a C2PA manifest store (http-delivery §8.9) | origin |
receipt | */rcpt/*.json | a receipt file (http-delivery §8.1) | origin |
playlist-receipt | */mr/*.json | a playlist receipt (http-delivery §8.6) | origin |
set | /.well-known/wai-sets/* | a parameter set under the origin’s well-known root (http-delivery §8.7) | origin |
key-log | /.well-known/wai-keys | the key log (http-delivery §8.4) | origin |
key-status | /.well-known/wai-key-status | key statuses (http-delivery §8.4) | origin |
grants | /.well-known/wai-grants/*.json | a module’s grants (http-delivery §8.4) | origin |
A pattern is RFC 8006 §4.1.5’s: * matches any run of characters, / among them, ? one
character that is not /, and $ before $, * or ? makes it a literal. A path’s class is
that of the first pattern, in the table’s order, that matches it; a path none matches is not
WAI’s and this text says nothing of it.
Freshness is the one rule that differs by class. origin: the cache stores the response and
keeps it fresh for as long as the origin’s Cache-Control says, neither longer nor shorter, and
does not revalidate it while it is fresh (http-delivery §9). revalidate: the cache revalidates
with its source on every use, as §9 rule 6 requires of a receipt index.
An object served under an alias (http-delivery §5.2), a parameter set under a root other than the origin’s well-known one, and a playlist are the deployment’s own paths: an upstream that wants a cache to hold them lists them after the ten classes, and this text’s reader does not read them.
4.2 The document
A configuration is a HostIndex with a HostMatch for the host WAI’s paths are served under.
The writer writes one host, in JCS (RFC 8785):
{"hosts":[{"host":"media.example","host-metadata":{
"metadata":[ <MI.SourceMetadata> ],
"paths":[
{"path-metadata":{"metadata":[ <the class's objects> ]},
"path-pattern":{"case-sensitive":true,"pattern":"*.wai.receipts"}},
… the nine other classes, in §4.1's order … ]}}]}
hostis written in lowercase and matched as RFC 8006 §4.1.2 matches it.- The host’s
metadataholds exactly one object,MI.SourceMetadata(RFC 8006 §4.2.1): one or more sources in order of preference, each{"endpoints":[…],"protocol":…}with at least one endpoint and a protocol ofhttp/1.1orhttps/1.1(RFC 8006 §7.3). This revision writes noacquisition-auth. - Each class’s
PathMetadataholds its objects (§4.3) and nopathsof its own. - Every object is written
{"generic-metadata-type":…,"generic-metadata-value":{…}, "mandatory-to-enforce":true}, with neither of RFC 8006 §4.1.7’s other two flags. - Nothing is given by reference: no object is a Link (RFC 8006 §4.3.1).
The host’s metadata is inherited by every path that does not define the same type (RFC 8006 §3.3), which is why it holds the sources and nothing else: an object placed there would apply to every class without appearing in any.
4.3 A class’s objects
A class carries, in the order written:
| form | objects |
|---|---|
cdni | MI.Cache, WAI.ByteStore |
open-caching | MI.Cache, MI.CachePolicy, MI.StaleContentCachePolicy, MI.AllowCompress, WAI.ByteStore |
Every class of one configuration is in the same form.
MI.Cache (RFC 8006 §4.2.6) is {"include-query-strings":[]}, with no exclude-path-pattern:
the cache key is the whole path and nothing of the query. A name is then one stored object,
whatever a request appends to it.
4.4 WAI.ByteStore
RFC 8006 has no object for range handling, for transformation, for request-header variation or
for a lifetime, and the open-caching objects cover the last of these only. WAI.ByteStore is a
GenericMetadata type of WAI’s own that states §9’s rules in one place. Its name identifies
whose it is, as RFC 8006 §6.5 recommends for a type outside the registry; it is not registered
in the CDNI Payload Types registry. Its value has exactly these members:
| member | value | the rule of http-delivery §9 it states |
|---|---|---|
version | 1 | |
store | "exact" | rule 1: stored and served byte for byte, never transformed, no content coding applied |
range | "single" | rule 2: a single byte range answered 206 with the exact bytes from a stored complete object, 416 with Content-Range: bytes */<len> where it cannot be satisfied |
headers | "origin" | rule 3: ETag, Content-Type, Cache-Control and, on a 200, Content-Length as the origin sent them |
vary | "none" | rule 4: a stored object varied by no request header |
if-range | "strong" | rule 5: If-Range evaluated with a strong comparison |
freshness | "origin" or "revalidate" | rule 6, and the class’s freshness (§4.1) |
otherwise | "relay" | rule 7: a request the cache cannot serve under these rules is passed through uncached and the origin’s bytes relayed unchanged |
A cache that lists WAI.ByteStore in its advertisement (§6) says it enforces all of them. One
value has one meaning: a later revision that adds a value or a member changes version.
4.5 The open-caching objects
In the open-caching form a class also states, in that interface’s own objects, the part of the
rules they can express. They say nothing WAI.ByteStore does not; they are there so that a cache
which applies those objects applies WAI’s values and not its defaults or a parent’s.
MI.CachePolicy(draft-ietf-cdni-cache-control-metadata-06§3.1). For a class whose freshness isorigin:{"external":"as-is","force-external":false,"force-internal":false, "internal":"as-is"}. Forindex:internalis"no-cache"andforce-internalistrue, so the cache revalidates on every use whatever the origin’s response says;externalstays"as-is".externalis"as-is"for every class: theCache-Controla client receives is the origin’s (rule 3).MI.StaleContentCachePolicy(draft-ietf-cdni-cache-control-metadata-06§3.3):{"failed-revalidation-delta-seconds":0, "stale-if-error":[],"stale-while-revalidating":false}. No stale response is served. For an object whose bytes never change a stale copy is the same bytes; for a receipt index, a key log and key statuses it is not, so the rule is one rule for every class.MI.AllowCompress(draft-ietf-cdni-edge-control-metadata-13§4):{"allow-compress":false}.
A class carries no MI.ComputedCacheKey (draft-ietf-cdni-cache-control-metadata-06 §3.5), which would key a stored
object by something other than its path, and no other type.
5. Reading a configuration
Inputs. The configuration’s text and the host. Output. The form, the host as written and the sources, or a refusal with one reason. A configuration that is accepted, written again from that output, is the writer’s bytes for it.
The reader refuses at the first of these steps that fails. Wherever a step reads an object of
RFC 8006’s or of §4, a value of another JSON type, a member the object’s definition does not
give it, or a required member that is absent is cdni_form, unless the step names another
reason.
-
The document. The text is JSON in which no object has a member name twice (jwp-receipts §3.1 step 1 reads JSON so), an object with exactly
hosts, an array:cdni_form. -
The host. The entries of
hostsare read in order to the first whosehost, in lowercase, is the host asked for, in lowercase. An entry met on the way that has a memberhrefiscdni_link: a HostMatch given by reference could be the host’s, and hosts are matched first to last. No such entry:cdni_host_missing. Entries after it are not read. -
Embedded. Any object within that HostMatch that has a member named
hrefiscdni_link. Then the HostMatch has exactlyhostandhost-metadata, and the HostMetadata exactlymetadataandpaths, both arrays. -
The host’s metadata. Each entry of
metadata, in order, is an object with exactlygeneric-metadata-type, a string,generic-metadata-value, an object, andmandatory-to-enforce, a boolean;mandatory-to-enforceoffalseiscdni_not_mandatory; and a type an earlier entry of the array has iscdni_metadata_duplicate. (RFC 8006 §3.3 has a receiver keep the first of two; a reader of WAI’s configuration refuses both.) Then the first entry whose type is notMI.SourceMetadataiscdni_computed_cache_keywhere it isMI.ComputedCacheKeyandcdni_metadata_unknownotherwise. NoMI.SourceMetadata:cdni_metadata_missing. Its value is as §4.2 says. -
The paths. Each entry of
pathsis an object with exactlypath-pattern, itself exactlypattern, a string, andcase-sensitive, a boolean, andpath-metadata, itself exactlymetadata, an array. Then, in this order:- a pattern of §4.1 that no entry has:
cdni_path_missing; - a pattern of §4.1 that two entries have, or the entries with §4.1’s patterns in another
order than the table’s:
cdni_path_order; - an entry with another pattern before the last entry with one of §4.1’s:
cdni_path_shadowed. Paths are matched first to last and only the first match is used (RFC 8006 §4.1.3), so such an entry may take a path of WAI’s, and the reader does not work out whether it does; - an entry with one of §4.1’s patterns whose
case-sensitiveisfalse:cdni_pattern_insensitive.
Entries after the last class are not read.
- a pattern of §4.1 that no entry has:
-
A class’s objects, for each class in §4.1’s order, step 7 for a class before step 6 for the next. Each entry of its
metadatais read as step 4 reads one, with its reasons. Then the first entry whose type is none of the five of §4.3 iscdni_computed_cache_keywhere it isMI.ComputedCacheKeyandcdni_metadata_unknownotherwise. Then the class’s types are exactly one form’s, in any order, and the same form as the classes before it: otherwisecdni_metadata_missing. The form ofindex, the first class, is the configuration’s. -
The class’s values, in this order:
MI.Cache: anything but exactlyinclude-query-strings, an empty array, iscdni_cache_key;MI.CachePolicy, in theopen-cachingform.internalandexternalare each a count of seconds or one of"as-is","no-cache"and"no-store", and the twoforce-members booleans; an absent member has the draft’s default,"as-is"andfalse. Forindex,internalother than"no-cache", orforce-internalnottrue:cdni_index_not_revalidated. For any other class,internalother than"as-is":cdni_ttl_override, forced or not, since an unforced value still applies wherever a response states no policy. Thenexternalother than"as-is":cdni_ttl_override. An"as-is"policy says the same forced or unforced;MI.StaleContentCachePolicy:stale-while-revalidatingoftrue, astale-if-errorthat lists anything, or afailed-revalidation-delta-secondsabove 0:cdni_stale_serving. Absent members have the draft’s defaults, which serve nothing stale;MI.AllowCompress:allow-compressoftrue:cdni_compression_allowed. Absent, it isfalse;WAI.ByteStore: a member §4.4 does not list, or aversionother than 1, iscdni_form. Then each member in this order, absent or of another value than §4.4’s:store,cdni_transform_allowed;range,cdni_range_rule_dropped;headers,cdni_headers_not_kept;vary,cdni_vary_allowed;if-range,cdni_if_range_weak;freshness,cdni_index_not_revalidatedforindexandcdni_ttl_overridefor any other class;otherwise,cdni_no_relay.
An accepted configuration states every rule of http-delivery §9 for every class, marks each mandatory, and lets no other entry take a path of WAI’s.
6. A cache’s advertisement
6.1 What a cache advertises
A cache that takes WAI’s configuration advertises three capabilities (RFC 8008 §5.1), each with the same footprint, in JCS:
{"capabilities":[
{"capability-type":"FCI.DeliveryProtocol","capability-value":{"delivery-protocols":["https/1.1"]},"footprints":[…]},
{"capability-type":"FCI.AcquisitionProtocol","capability-value":{"acquisition-protocols":["https/1.1"]},"footprints":[…]},
{"capability-type":"FCI.Metadata","capability-value":{"metadata":["MI.SourceMetadata","MI.Cache","WAI.ByteStore"]},"footprints":[…]}]}
FCI.Metadata (RFC 8008 §5.7) lists MI.SourceMetadata and then the types of the form it
supports, in §4.3’s order. RFC 8008 §5.7 reads the list as the only types the cache supports, so
a cache that lists the open-caching form’s types supports the cdni form too.
6.2 Footprints
A footprint is written from regions in strictly ascending order of their bytes, each mapped to CDNI’s lowercase as rung-price §2 maps it:
- no region: no
footprintsmember, and the capability holds everywhere; - countries only: one footprint of type
countrycode(RFC 8006 §4.3.8); - subdivisions only: one of type
subdivisioncode(RFC 9388 §2.1); - both: one of type
footprintunion(RFC 9388 §2.2) whose value is thecountrycodefootprint, then thesubdivisioncodeone.
A footprint object holds a region r: a countrycode one when it lists r’s country; a
subdivisioncode one when it lists r; a footprintunion when one of its members holds r. A
subdivision’s footprint never holds its country, as rung-price §2’s holds never does. A
capability covers r when it has no footprints or every footprint object of its
footprints holds r: several footprint objects on one capability narrow it (RFC 9388 §2.2).
6.3 Whether an advertisement supports a configuration
Inputs. The advertisement’s text; a configuration’s form and the protocols of its sources; the protocol the cache is to deliver by; and a region. The check is refused at the first of these that fails:
- The text is JSON as §5 step 1 reads it, an object with exactly
capabilities, an array. Each entry is an object with exactlycapability-type, a string, andcapability-value, an object, and optionallyfootprints. The value of anFCI.DeliveryProtocol, anFCI.AcquisitionProtocolor anFCI.Metadataentry has exactly its one member (delivery-protocols,acquisition-protocols,metadata), an array of strings. An entry of another type is read no further than its footprints. Otherwisecdni_advert_form. - Every entry’s footprints are read, entry by entry and in order, whatever the entry’s type.
footprintsis an array of objects with exactlyfootprint-type, a string, andfootprint-value, an array: otherwisecdni_advert_form. Afootprintunionwhose value holds an entry that is not an object, or is itself afootprintunion, iscdni_advert_form(RFC 9388 §2.2). A footprint of any type other than the three of §6.2, or a value of acountrycodeorsubdivisioncodefootprint that is not CDNI’s lowercase writing of a region code of that kind, iscdni_footprint_unmapped: an address block or a network number is not a region, and the check does not guess whether it lies in one. - No
FCI.DeliveryProtocolentry that covers the region lists the delivery protocol:cdni_delivery_unsupported. - A source’s protocol that no
FCI.AcquisitionProtocolentry covering the region lists:cdni_acquisition_unsupported. - No single
FCI.Metadataentry that covers the region listsMI.SourceMetadataand every type of the form (§4.3), compared without regard to case:cdni_capability_missing. The cache could not enforce an object the configuration marks mandatory, and RFC 8006 §6.6 would have it serve nothing.
An upstream SHOULD NOT delegate WAI’s paths to a cache whose advertisement fails this check for the region it would serve. An advertisement is the cache’s own unsigned word and places no key (§7).
7. Roles and records
This text adds no authority and no record. A cache that takes a configuration is, in the other texts’ terms:
- A transparent byte store under jwp-receipts §4.5, bound by jwp-receipts §4.3: it forwards
every envelope and receipt unaltered. A cache that serves other bytes than an object’s derives
a new object, which needs
edge/derivefrom the source’s origin and receipts of its own (deriving-edge §3.2, §8); no configuration grants that. - A node of cache-authority, where its operator lists its key with
cache/servein the operator’s own key log (cache-authority §4.3). A configuration and an advertisement name no key and place none: a server key is placed by the heads a relying party names (cache-authority §4.4), and a cache with no listed key is served from and verified as any other, and reportedserver_not_listed. - Accounted on signed records. What a cache served is the receiver’s acknowledgement naming
the cache’s key as
upstream, or the cache’s own declaration (settlement §3, §4), and a statement recomputes from them. A cache that exchanges CDNI logs maps each item onto a logging record as settlement §9.1 says; a log is the serving side’s word and is read as a declaration, never as an acknowledgement. How many of a region’s receivers held an object by a deadline is cache-authority §8’s tally, whose region is the code §6.2 writes in lowercase. - Held to the rules by test, not by trust.
cache-conformance/runs http-delivery §9’s tests against a running cache with its configuration. A sink relies on neither the test nor the configuration (§3).
8. Reasons
The codes this text adds, each with where it is raised:
| reason | raised at |
|---|---|
cdni_form | §5 |
cdni_link | §5 steps 2 and 3 |
cdni_host_missing | §5 step 2 |
cdni_not_mandatory | §5 steps 4 and 6 |
cdni_metadata_duplicate | §5 steps 4 and 6 |
cdni_computed_cache_key | §5 steps 4 and 6 |
cdni_metadata_unknown | §5 steps 4 and 6 |
cdni_metadata_missing | §5 steps 4 and 6 |
cdni_path_missing | §5 step 5 |
cdni_path_order | §5 step 5 |
cdni_path_shadowed | §5 step 5 |
cdni_pattern_insensitive | §5 step 5 |
cdni_cache_key | §5 step 7 |
cdni_ttl_override | §5 step 7 |
cdni_index_not_revalidated | §5 step 7 |
cdni_stale_serving | §5 step 7 |
cdni_compression_allowed | §5 step 7 |
cdni_transform_allowed | §5 step 7 |
cdni_range_rule_dropped | §5 step 7 |
cdni_headers_not_kept | §5 step 7 |
cdni_vary_allowed | §5 step 7 |
cdni_if_range_weak | §5 step 7 |
cdni_no_relay | §5 step 7 |
cdni_advert_form | §6.3 steps 1 and 2 |
cdni_footprint_unmapped | §6.3 step 2 |
cdni_delivery_unsupported | §6.3 step 3 |
cdni_acquisition_unsupported | §6.3 step 4 |
cdni_capability_missing | §6.3 step 5 |
A writer refuses, as cdni_form, a host that is empty or not in lowercase and sources §4.2 does
not admit, and, as cdni_advert_form, regions that are not region codes in strictly ascending
order and a protocol RFC 8006 §7.3 does not register; a check asked for a region that is not a
region code is refused as cdni_advert_form too.
9. Conformance
cache-conformance/cdni/ holds the corpus, written by
wai_cdni_vectors gen as vectors.json. Nothing in it is signed. It has:
- Written configurations in each form and advertisements for no region, countries, subdivisions and both, each as the bytes the writer gives.
- Configurations, each with the host asked for and what the reader gives: the two forms as
written; a host asked in capitals; another host first; a class’s objects in another order; a
type in lowercase; a path after the classes; the open-caching objects with their defaults; an
as-is policy forced; two sources and a host with a port. Refused: text that is not JSON, a
member twice, and an object out of form at each level; a Link in
hosts, for the host’s metadata and for a class’s; no HostMatch for the host; an object marked not mandatory; a type twice; a computed cache key on a class and in the host’s metadata; a type no class carries, on a class and at the host; no sources, noWAI.ByteStore, a class short of one open-caching object, and two forms in one configuration; a class missing, out of order and twice; a path before the classes and between them; a pattern matched without case; a query parameter in the key, the query default and part of the path left out; a lifetime on an immutable class forced and unforced,no-store, an external lifetime, an index whose external policy is rewritten, and aWAI.ByteStorefreshness changed and dropped; an index not revalidated in each of three ways; each of the three ways of serving stale; compression; each rule ofWAI.ByteStorechanged, and its range rule dropped; and two faults at once, in two classes and in two steps, each refused for the earlier. - Advertisements, each with a form, protocols and a region: every case of §6.2’s holds
and covers; types in another case; a capability of another type; two metadata entries of
which one supports. Refused: each defect of form, a union in a union among them; a footprint
of addresses, of a network, a country in capitals and a subdivision among countries; a
protocol not advertised for delivery and for acquisition; a region outside the footprint, a
subdivision asked for its country, and two footprints that narrow to nothing; and a metadata
capability that lacks
WAI.ByteStore, lacks the open-caching types, is split over two entries or is advertised elsewhere. - Paths, each with its class or none.
A conforming implementation gives every case the outcome the corpus states.
wai_cdni_vectors verify and the test tests/cdni.rs check that the file regenerates byte for
byte, that wai-rs gives every case its outcome, that every reason of §8 appears, and that §8
and §4.1 list exactly the reference’s codes and classes.
cache-conformance/cdni_verify.py is the second implementation, written from this text: it
shares no code with wai-rs, uses the standard library alone, writes every configuration and
advertisement itself and compares the bytes, reads every case, reads §4.1 and §8 from this text,
mutates copies of the corpus and requires every copy to fail, and drops each of its own checks
in turn and requires the corpus to catch the weakened verifier.
10. Security considerations
- A configuration protects no one. It is the upstream’s request. The protection is the sink’s: it verifies what it is served, and a cache that ignores its configuration is refused byte by byte. The reader’s refusals keep a publisher from handing out a configuration that asks a cache to break the rules; they say nothing of what a cache does.
- Mutable resources are where a cache can hurt. An object’s bytes are held to its name. A receipt index, a key log and key statuses change, and a stale one withholds a claim, a revocation or a status. So the index is revalidated on every use, nothing is served stale, and the freshness of the rest is the origin’s. A verifier anchors an origin only from a key log it retrieved from the origin itself (http-delivery §8.4), so a cache’s copy never moves an anchor.
- What a cache learns. It sees each request for the paths it serves, as any cache does, and the configuration tells it nothing more. A configuration names the upstream’s sources, which the upstream chooses to show the cache.
- An unregistered type.
WAI.ByteStoreis in no registry. Another party could give the name another meaning;versionand the exact member list are what a reader holds it to, and a cache that lists the name without enforcing it is found by test (§7), and harms no sink (§3). - Bounded work. A reader makes one pass over one HostMatch; a pattern match is the product of the pattern’s and the path’s lengths; an advertisement’s footprints are each read once.