<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.6.36 (Ruby 3.2.2) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-group-privacypass-k-check-00" category="std" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.17.4 -->
  <front>
    <title abbrev="K-Check">The K-Check Protocol for HTTP Resource Consistency</title>
    <seriesInfo name="Internet-Draft" value="draft-group-privacypass-k-check-00"/>
    <author initials="B." surname="Beurdouche" fullname="Benjamin Beurdouche">
      <organization>Inria &amp; Mozilla</organization>
      <address>
        <email>ietf@beurdouche.com</email>
      </address>
    </author>
    <author initials="M." surname="Finkel" fullname="Matthew Finkel">
      <organization>Apple Inc.</organization>
      <address>
        <email>sysrqb@apple.com</email>
      </address>
    </author>
    <author initials="S." surname="Valdez" fullname="Steven Valdez">
      <organization>Google LLC</organization>
      <address>
        <email>svaldez@chromium.org</email>
      </address>
    </author>
    <author initials="C. A." surname="Wood" fullname="Christopher A. Wood">
      <organization>Cloudflare</organization>
      <address>
        <email>caw@heapingbits.net</email>
      </address>
    </author>
    <date year="2023" month="July" day="10"/>
    <area>Security</area>
    <workgroup>Privacy Pass</workgroup>
    <keyword>token</keyword>
    <keyword>extensions</keyword>
    <abstract>
      <?line 55?>

<t>This document describes a protocol called K-Check for implementing HTTP resource consistency checks.
The primary use case for K-Check is for deployments of protocols such as Privacy Pass and Oblivious
HTTP in which privacy goals require that clients have a consistent view of some protocol-specific
resource (typically, a public key).</t>
    </abstract>
    <note removeInRFC="true">
      <name>About This Document</name>
      <t>
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-group-privacypass-k-check/"/>.
      </t>
      <t>
        Discussion of this document takes place on the
        Privacy Pass Working Group mailing list (<eref target="mailto:privacy-pass@ietf.org"/>),
        which is archived at <eref target="https://mailarchive.ietf.org/arch/browse/privacy-pass/"/>.
        Subscribe at <eref target="https://www.ietf.org/mailman/listinfo/privacy-pass/"/>.
      </t>
      <t>Source for this draft and an issue tracker can be found at
        <eref target="https://github.com/chris-wood/draft-group-privacypass-K-Check"/>.</t>
    </note>
  </front>
  <middle>
    <?line 62?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>Privacy-enhancing protocols such as Privacy Pass <xref target="PRIVACYPASS"/> and Oblivious HTTP <xref target="OHTTP"/>
require clients to obtain and use a public key for execution. In Privacy Pass,
public keys are used by clients when issuing and redeeming tokens for anonymous
authorization. In Oblivious HTTP (OHTTP), clients use public keys to encrypt
messages to a gateway server.</t>
      <t>Deployments of protocols such as Privacy Pass and OHTTP requires that very large sets of clients
share the same key, or even that all clients globally share the same key. This is because the privacy properties depend on the client
anonymity set size. In other words, the key that's used determines the set to which
a particular client belongs. Using a unique, client-specific key would yield an anonymity set
of size one, therefore violating the desired privacy goals of the system. Clients that
use the same key as one another are said to have a consistent view of the key.</t>
      <t><xref target="CONSISTENCY"/> describes this notion of consistency in more detail. It also outlines
several designs that can be used as the basis for consistency systems. This document is
a concrete instantiation of one of those designs, "Shared Cache Discovery". In particular,
this document describes a protocol called K-Check, based on <xref target="DOUBLE-CHECK"/>,
for checking that an HTTP resource is consistent with the view of one or more so-called mirrors.
In this context, a mirror is an HTTP resource that fetches and caches copies of an HTTP resource
for clients to use for consistency checks. More specifically, clients obtain copies of
a desired resource from a mirror and then compare those copies to their resource.</t>
      <t>K-Check is a generic protocol for consistency checks of HTTP resources, and therefore is suitable
for any protocol that needs consistency of an HTTP resource. <xref target="profile-privacypass"/> and <xref target="profile-ohttp"/>
describe Privacy Pass and OHTTP profiles for K-Check, respectively.</t>
    </section>
    <section anchor="conventions-and-definitions">
      <name>Conventions and Definitions</name>
      <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>
      <?line -18?>

</section>
    <section anchor="terminology">
      <name>Terminology</name>
      <t>The following terms are used throughout this document:</t>
      <ul spacing="normal">
        <li>Resource: A HTTP resource identified by a URL.</li>
        <li>Normalized resource representation: A unique or otherwise protocol-specific representation
that is derived from an HTTP resource. The process of normalization is specific to a
protocol and the resource in question.</li>
        <li>Mirror: A HTTP resource that fetches and caches HTTP resources.</li>
      </ul>
    </section>
    <section anchor="mirror-protocol">
      <name>Mirror Protocol</name>
      <t>The mirror protocol is a simple HTTP-based protocol similar to a reverse proxy. Each mirror
resource, henceforth referred to as a mirror, is identified by a Mirror URI Template <xref target="RFC6570"/>.
The scheme for the Mirror URI Template <bcp14>MUST</bcp14> be "https". The Mirror URI Template uses the Level
3 encoding defined <xref section="1.2" sectionFormat="of" target="RFC6570"/> and contains one variables: "target", which is the
percent-encoded URL of a HTTP resource to be mirrored. Example Mirror URI Templates are shown below.</t>
      <artwork><![CDATA[
https://mirror.example/mirror{?target}
https://mirror.example/{target}
]]></artwork>
      <t>The Mirror URI Template <bcp14>MUST</bcp14> contain the "target" variable exactly once. The variable
<bcp14>MUST</bcp14> be within the path or query components of the URI.</t>
      <t>In addition, each mirror is configured with a MIN_VALIDITY_WINDOW parameter, which is an integer
indicating the minimum time for resources the mirror will cache according to their "max-age"
response directive. We refer to the validity window of the mirror response as the period of
time determined by the Cache-Control headers as the response.</t>
      <t>Clients send requests to mirror resources after being configured with their corresponding
Mirror URI Template. Clients <bcp14>MUST</bcp14> ignore configurations that do not conform to this template.</t>
      <t>Upon receipt of a mirror request, mirrors validate the incoming request. If the request is invalid
or malformed, e.g., the "target" parameter is not a correctly encoded URL, the mirror aborts
and returns a a 4xx (Client Error) to the client. The mirror <bcp14>SHOULD</bcp14> check that the target resource
identified by the "target" parameter is allowed by policy, e.g., so that it is not abused to
fetch arbitrary resources. One way to implement this check is via an allowlist of target URLs.</t>
      <t>If the request is valid and allowed, the mirror checks to see if it has a cached version of the
resource identified by the target URL. Mirrors can provide a cached response to a client request
if the following criteria are met:</t>
      <ol spacing="normal" type="1"><li>The target URL matches that of a cached response.</li>
        <li>The cached response is fresh according to its Cache-Control header (see <xref section="4.2" sectionFormat="of" target="CACHING"/>).</li>
      </ol>
      <t>If both criteria are met, the mirror encodes the cached response using Binary HTTP <xref target="BHTTP"/>
and returns it to the client in a response. The mirror response incldues a Cache-Control header
with "max-age" directive set to that of the cached response.</t>
      <t>Otherwise, mirrors send a GET request to the target resource URL, copying the Accept header from
the client request if present. If this request fails, the mirror returns a 4xx error to the client.
Otherwise, the response to a mirror request is the content that was contained in the target resource.
If this request suceeeds, the mirror checks it for validity. The response is considered valid and stored
in the mirror's cache if the following criteria are met:</t>
      <ol spacing="normal" type="1"><li>The response can be cached according to the rules in <xref section="3" sectionFormat="of" target="CACHING"/>. In particular,
if the request had a Vary header, this is used in determining whether the mirror's response is valid.</li>
        <li>The Cache-Control header is present, has a "max-age" response directive that is
greater than or equal to MIN_VALIDITY_WINDOW, and does not have a "no-store" or "private" directive.</li>
      </ol>
      <t>If the response is valid, the response is stored in the mirror's cache. Mirrors purge this cache when
the response is no longer valid according to the Cache-Control headers.</t>
      <t>To complete the client request, the mirror then encodes the response using Binary
HTTP <xref target="BHTTP"/> and returns it to the client in a response. The mirror response incldues a
Cache-Control header with "max-age" directive set to that of the cached response.</t>
      <t>Clients recover the target's mirrored response by Binary HTTP decoding the mirror response
content.</t>
      <section anchor="mirror-request-and-respnose-example">
        <name>Mirror Request and Respnose Example</name>
        <t>The following example shows two mirror request and response examples. The first one yields a mirror
cache miss and the second one yields a mirror cache hit. The Mirror URI Template is
"https://mirror.example/mirror{?target}", and the target URL is
"https://issuer.example/.well-known/private-token-issuer-directory".</t>
        <t>The first client request to the mirror might be the following.</t>
        <artwork><![CDATA[
:method = GET
:scheme = https
:authority = mirror.example
:path = /mirror?target=https%3A%2F%2Fissuer.example%2F.well-known%2Fprivate-token-issuer-directory
accept = application/private-token-issuer-directory
]]></artwork>
        <t>Upon receipt, the mirror decodes the "target" parameter, inspects its cache for a copy of the
resource, and then constructs a HTTP request to the target URL to fetch the content. If present,
the relay copies the Accept header from the client request to the request sent to the target.
This mirror request to the target might be the following.</t>
        <artwork><![CDATA[
:method = GET
:scheme = https
:authority = target.example
:path = /.well-known/private-token-issuer-directory
accept = application/private-token-issuer-directory
]]></artwork>
        <t>The target response is then returned to the mirror, like so:</t>
        <artwork><![CDATA[
:status = 200
content-type = application/private-token-issuer-directory
content-length = ...
cache-control: max-age=3600

<Bytes containing a private token issuer directory>
]]></artwork>
        <t>The mirror caches this response content for the target URL, encodes it using Binary HTTP <xref target="BHTTP"/>,
and then returns the response to the client:</t>
        <artwork><![CDATA[
:status = 200
content-length = ...
cache-control: max-age=3600

<Bytes containing the target's BHTTP-encoded response>
]]></artwork>
        <t>When a second client asks for the same request by the mirror it can be served with the cached
copy. The second client's request might be the following:</t>
        <artwork><![CDATA[
:method = GET
:scheme = https
:authority = mirror.example
:path = /mirror?target=https%3A%2F%2Fissuer.example%2F.well-known%2Fprivate-token-issuer-directory
]]></artwork>
        <t>The mirror validates the request, locates the cached copy of the
"https://issuer.example/.well-known/private-token-issuer-directory" content, and then
returns it to the client without updating its cached copy.</t>
        <artwork><![CDATA[
:status = 200
content-length = ...
cache-control: max-age=3600

<Bytes containing the target's BHTTP-encoded response>
]]></artwork>
      </section>
    </section>
    <section anchor="k-check">
      <name>K-Check</name>
      <t>Clients are configured with the URLs for one or more mirror resources. Each URL identifies an API
endpoint that clients use to obtain mirrored copies of a resource.</t>
      <t>The input to K-Check is a candidate HTTP resource, a target URL at which the resource
was obtained, and a representation of the input resource. To check this
resource, the client runs the following steps for each configured mirror.</t>
      <ol spacing="normal" type="1"><li>Send a mirror request to the mirror for the target URL. If the request fails, fail
this mirror check.</li>
        <li>Otherwise, compute the first valid representation of the resource based on the mirror's response.</li>
        <li>Compare the computed representation to the input representation. If they do not match,
fail this mirror check. Otherwise, this mirror check succeeds.</li>
      </ol>
      <t>If all mirror checks succeed, the client outputs success. Otherwise, the client has
detected an inconsistency and outputs fail.</t>
      <t>[[OPEN ISSUE: Can mirrors somehow communicate the number of “active users” to clients? How would mirrors determine client uniqueness? And finally, if mirrors did this accurately, how would clients use this information?]]</t>
      <section anchor="profile-privacypass">
        <name>Privacy Pass Profile</name>
        <t>Clients are given as input an issuer token key from an origin server and want to check
whether it is consistent with the key that is given to other clients. Let the input key
be denoted token_key and its identifier be token_key_id. Clients are also given as input
the name of the issuer, from which they can construct the target URL for the issuer
directory. If clients have already checked this issuer’s token key, i.e., they’ve
previously run K-Check, they can simply reuse the result up to its expiration. Otherwise,
clients invoke K-Check in parallel with the issuance protocol.</t>
        <t>Each issuer directory can yield one or more normalized representations that clients use
in the K-Check protocol. For example, given a mirrored token directory resource like the
following:</t>
        <artwork><![CDATA[
{
  "issuer-request-uri": "https://issuer.example.net/request",
  "token-keys": [
    {
      "token-type": 2,
      "token-key": "MI...AB",
      "not-before": 1686913811,
    },
    {
      "token-type": 2,
      "token-key": "MI...AQ",
    }
  ]
}
]]></artwork>
        <t>Clients compute the first valid representation of this directory, i.e., the first entry in the list that the client can use, which might be the key ID
of the first key in the "token-keys" list (depending on the "not-before" value), or the
key ID of the second key in the "token-keys" list. The key ID is computed as defined in
<xref section="6.5" sectionFormat="of" target="PRIVACYPASS-ISSUANCE"/>.</t>
      </section>
      <section anchor="profile-ohttp">
        <name>Oblivious HTTP Profile</name>
        <t>Clients can run K-Check for OHTTP in several ways depending on the deployment. In practice,
common deployments are as follows:</t>
        <ol spacing="normal" type="1"><li>Clients are configured with gateway configurations; and</li>
          <li>Clients fetch gateway configurations before use.</li>
        </ol>
        <t>In both cases, clients begin with a gateway configuration and want to check it for consistency.
In OHTTP, there is exactly one representation for a gateway configuration – the configuration itself.
Before using the configuration to encrypt a binary HTTP message to the gateway, clients can run
K-Check with their configured mirrors to ensure that this configuration is correct for the given gateway.</t>
      </section>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <t>K-Check assumes that at least one client-configured mirror is honest. Under this assumption,
the consistency properties of K-Check are as follows:</t>
      <ol spacing="normal" type="1"><li>With honest mirrors, clients that successfully check a resource are assured that they
share the same copy of the resource with the union of mirror clients for each configured mirror.</li>
        <li>Consistency only holds for the period of time of the minimum mirror validity window.</li>
        <li>With at least one dishonest mirror, the probability of discovering an inconsistency is 1 - (1 / 2^(k-1)).
This is the probability that each individual mirror check succeeds in the mirror protocol.</li>
      </ol>
      <t>Unless all clients share the same configured mirrors, K-Check does not achieve global consistency
as is defined in <xref target="CONSISTENCY"/>.</t>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>This document has no IANA actions.</t>
    </section>
  </middle>
  <back>
    <references>
      <name>References</name>
      <references>
        <name>Normative References</name>
        <reference anchor="PRIVACYPASS">
          <front>
            <title>The Privacy Pass Architecture</title>
            <author fullname="Alex Davidson" initials="A." surname="Davidson">
              <organization>LIP</organization>
            </author>
            <author fullname="Jana Iyengar" initials="J." surname="Iyengar">
              <organization>Fastly</organization>
            </author>
            <author fullname="Christopher A. Wood" initials="C. A." surname="Wood">
              <organization>Cloudflare</organization>
            </author>
            <date day="15" month="June" year="2023"/>
            <abstract>
              <t>   This document specifies the Privacy Pass architecture and
   requirements for its constituent protocols used for constructing
   privacy-preserving authentication mechanisms.  It provides
   recommendations on how the architecture should be deployed to ensure
   the privacy of clients and the security of all participating
   entities.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-privacypass-architecture-13"/>
        </reference>
        <reference anchor="PRIVACYPASS-ISSUANCE">
          <front>
            <title>Privacy Pass Issuance Protocol</title>
            <author fullname="Sofia Celi" initials="S." surname="Celi">
              <organization>Brave Software</organization>
            </author>
            <author fullname="Alex Davidson" initials="A." surname="Davidson">
              <organization>Brave Software</organization>
            </author>
            <author fullname="Steven Valdez" initials="S." surname="Valdez">
              <organization>Google LLC</organization>
            </author>
            <author fullname="Christopher A. Wood" initials="C. A." surname="Wood">
              <organization>Cloudflare</organization>
            </author>
            <date day="26" month="June" year="2023"/>
            <abstract>
              <t>   This document specifies two variants of the two-message issuance
   protocol for Privacy Pass tokens: one that produces tokens that are
   privately verifiable using the issuance private key, and another that
   produces tokens that are publicly verifiable using the issuance
   public key.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-privacypass-protocol-11"/>
        </reference>
        <reference anchor="CONSISTENCY">
          <front>
            <title>Key Consistency and Discovery</title>
            <author fullname="Alex Davidson" initials="A." surname="Davidson">
              <organization>Brave Software</organization>
            </author>
            <author fullname="Matthew Finkel" initials="M." surname="Finkel">
              <organization>The Tor Project</organization>
            </author>
            <author fullname="Martin Thomson" initials="M." surname="Thomson">
              <organization>Mozilla</organization>
            </author>
            <author fullname="Christopher A. Wood" initials="C. A." surname="Wood">
              <organization>Cloudflare</organization>
            </author>
            <date day="10" month="July" year="2023"/>
            <abstract>
              <t>   This document describes the consistency requirements of protocols
   such as Privacy Pass, Oblivious DoH, and Oblivious HTTP for user
   privacy.  It presents definitions for consistency and then surveys
   mechanisms for providing consistency in varying threat models.  In
   concludes with discussion of open problems in this area.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-privacypass-key-consistency-01"/>
        </reference>
        <reference anchor="OHTTP">
          <front>
            <title>Oblivious HTTP</title>
            <author fullname="Martin Thomson" initials="M." surname="Thomson">
              <organization>Mozilla</organization>
            </author>
            <author fullname="Christopher A. Wood" initials="C. A." surname="Wood">
              <organization>Cloudflare</organization>
            </author>
            <date day="15" month="March" year="2023"/>
            <abstract>
              <t>   This document describes a system for forwarding encrypted HTTP
   messages.  This allows a client to make multiple requests to an
   origin server without that server being able to link those requests
   to the client or to identify the requests as having come from the
   same client, while placing only limited trust in the nodes used to
   forward the messages.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-ohai-ohttp-08"/>
        </reference>
        <reference anchor="RFC2119">
          <front>
            <title>Key words for use in RFCs to Indicate Requirement Levels</title>
            <author fullname="S. Bradner" initials="S." surname="Bradner"/>
            <date month="March" year="1997"/>
            <abstract>
              <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="2119"/>
          <seriesInfo name="DOI" value="10.17487/RFC2119"/>
        </reference>
        <reference anchor="RFC8174">
          <front>
            <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
            <author fullname="B. Leiba" initials="B." surname="Leiba"/>
            <date month="May" year="2017"/>
            <abstract>
              <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="8174"/>
          <seriesInfo name="DOI" value="10.17487/RFC8174"/>
        </reference>
        <reference anchor="RFC6570">
          <front>
            <title>URI Template</title>
            <author fullname="J. Gregorio" initials="J." surname="Gregorio"/>
            <author fullname="R. Fielding" initials="R." surname="Fielding"/>
            <author fullname="M. Hadley" initials="M." surname="Hadley"/>
            <author fullname="M. Nottingham" initials="M." surname="Nottingham"/>
            <author fullname="D. Orchard" initials="D." surname="Orchard"/>
            <date month="March" year="2012"/>
            <abstract>
              <t>A URI Template is a compact sequence of characters for describing a range of Uniform Resource Identifiers through variable expansion. This specification defines the URI Template syntax and the process for expanding a URI Template into a URI reference, along with guidelines for the use of URI Templates on the Internet. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="6570"/>
          <seriesInfo name="DOI" value="10.17487/RFC6570"/>
        </reference>
        <reference anchor="BHTTP">
          <front>
            <title>Binary Representation of HTTP Messages</title>
            <author fullname="M. Thomson" initials="M." surname="Thomson"/>
            <author fullname="C. A. Wood" initials="C. A." surname="Wood"/>
            <date month="August" year="2022"/>
            <abstract>
              <t>This document defines a binary format for representing HTTP messages.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9292"/>
          <seriesInfo name="DOI" value="10.17487/RFC9292"/>
        </reference>
      </references>
      <references>
        <name>Informative References</name>
        <reference anchor="DOUBLE-CHECK">
          <front>
            <title>Key Consistency by Double-Checking via a Semi-Trusted Proxy</title>
            <author fullname="Benjamin M. Schwartz" initials="B. M." surname="Schwartz">
              <organization>Google LLC</organization>
            </author>
            <date day="19" month="October" year="2022"/>
            <abstract>
              <t>   Several recent IETF privacy protocols require clients to acquire
   bootstrap information for a service in a way that guarantees both
   authenticity and consistency, e.g., encrypting to the same key as
   many other users.  This specification defines a procedure for
   transferring arbitrary HTTP resources in a manner that provides these
   guarantees.  The procedure relies on access to a semi-trusted HTTP
   proxy, under the same security assumptions as an Oblivious HTTP
   Relay.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-schwartz-ohai-consistency-doublecheck-03"/>
        </reference>
        <reference anchor="CACHING">
          <front>
            <title>HTTP Caching</title>
            <author fullname="R. Fielding" initials="R." role="editor" surname="Fielding"/>
            <author fullname="M. Nottingham" initials="M." role="editor" surname="Nottingham"/>
            <author fullname="J. Reschke" initials="J." role="editor" surname="Reschke"/>
            <date month="June" year="2022"/>
            <abstract>
              <t>The Hypertext Transfer Protocol (HTTP) is a stateless application-level protocol for distributed, collaborative, hypertext information systems. This document defines HTTP caches and the associated header fields that control cache behavior or indicate cacheable response messages.</t>
              <t>This document obsoletes RFC 7234.</t>
            </abstract>
          </front>
          <seriesInfo name="STD" value="98"/>
          <seriesInfo name="RFC" value="9111"/>
          <seriesInfo name="DOI" value="10.17487/RFC9111"/>
        </reference>
      </references>
    </references>
    <?line 348?>

<section numbered="false" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>This document is based on the <xref target="DOUBLE-CHECK"/> protocol from Benjamin Schwartz.</t>
    </section>
  </back>
  <!-- ##markdown-source:
H4sIAAAAAAAAA9Vb624bR5b+X09Rw2A29oKkIzuTSbRxHElWYmFsSWNJMYIg
GxS7i2Stm91MV7dkRlCQd9hfA8wC+yz7KHmS/c6pS1c3qcxkJsBiEUOR2F11
LnXOdy51OJlMRGOaQu/L0eVSyz9NjpY6eyvP66qpsqqQ86qWLy4vz+Vrbau2
zrQ8qkprbKPLbDMSajar9TUW+4UjkalGL6p6sy9tkwuRV1mpVtg+r9W8mSzq
ql1P1rW5VtlmraydvJ1ktHDywQfCtrOVsdZUZbNZY8nJ8eUXomxXM13vixz7
7osMxHVpW7svm7rVAqSfCFVrBRYudNbWpgFXN1X9linh03NHS56D2Ei81Rs8
zPeFnMimeqtL+kW/gzRE1oprXbYgI+Xu5VI6zkZvQMGUC/klvUafr5Qp8LmX
bEKifW50M59W9YKeL0yzbGd4I1vWxk5uqip/dJ9Koi6FaptlVRO32EJKU0Lu
w6k81G2dVy0Uxx87BR/q8j/UypTDp2BAleYH1UBA6LSsjZL/Il9VP5iiUPyG
dswTu5/P4uJpVq16hF9N5RemfKuLhOgr1TRLfZM+AL19ebBeFxrEsmlKwW5s
/f3sc0UPt7a/mMqvVJHrH5LtLxqNE0k/592/rKoFtn/58qi3+zW/9jk0XK1M
uyLV9ygcTeXBVL6B6hMSR3QeTbVe6rr3lAkdFVWbzwsYWEooUzefL7VawwBm
prHTUjdClFW9go6v2XrOX598dXD09fnBxQVUPnk+Jd32zljV2dI0Omta3jtZ
MDm5uLg6OD06vmfl2rsmVh2dnV6cXFwenx59fc/LsPdJ1jks1pyRNydvV0tl
8KNp1kKYcp5K8fzs6vDl8eToxfHRn9wKmy1vVN384FYlG09gM7NCsysLISaT
iVQz29Qqg2oul8ZKAEG70mUjc22z2sy0lUoGWaDSotB5hB9CHbOCldAK8jOG
oDpAUEJYMkk7FYRekHyl6o1sLd5R+EH7hD3BA/2Z63VRbWhfK6t55MBKC6OX
ysrU46Uqc3k2K8y1qVormAt42M3S4F2vZ7moFJbX+vvW1Fo2S9XIrDBMYKmu
NcSM/Dby2sBbQNdWKx2JT+xaZ2ZuMhFFfACgMaSVzZj0BOWaTOI0H06ddlcm
zwstxHtwsqau8jYj/xbCcz/R5VKVGanub0h4e5vY3t1dX2Kn99tbNpq7OxGE
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
OBxXT4alKY2N3+C78F+zmor/BdPS5C6gOQAA

-->

</rfc>
