<?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.11 (Ruby 3.1.2) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-schwartz-ohai-consistency-doublecheck-01" category="std" consensus="true" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.12.10 -->
  <front>
    <title abbrev="Key Consistency Double Check">Key Consistency for Oblivious HTTP by Double-Checking</title>
    <seriesInfo name="Internet-Draft" value="draft-schwartz-ohai-consistency-doublecheck-01"/>
    <author fullname="Benjamin M. Schwartz">
      <organization>Google LLC</organization>
      <address>
        <email>bemasc@google.com</email>
      </address>
    </author>
    <date year="2022" month="June" day="28"/>
    <area>sec</area>
    <workgroup>ohai</workgroup>
    <keyword>Internet-Draft</keyword>
    <abstract>
      <t>The assurances provided by Oblivious HTTP depend on the client's ability to verify that it is using the same Request Resource and KeyConfig as many other users.  This specification defines a protocol to enable this verification.</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-schwartz-ohai-consistency-doublecheck/"/>.
      </t>
      <t>Source for this draft and an issue tracker can be found at
        <eref target="https://github.com/bemasc/access-services"/>.</t>
    </note>
  </front>
  <middle>
    <section anchor="introduction">
      <name>Introduction</name>
      <t>Oblivious HTTP <xref target="I-D.ietf-ohai-ohttp"/> presumes at least three parties to each exchange: the client, the proxy, and the target (formally, the Oblivious Request Resource).  When used properly, Oblivious HTTP enables the client to send requests to the target in such a way that the target cannot tell whether two requests came from the same client and the proxy cannot see the contents of the requests.</t>
      <t>Oblivious HTTP's threat model assumes that at least one of the proxy and the target is acting properly, i.e. complying with the protocol and keeping certain information confidential.  If either proxy or target misbehaves, the only effect must be a denial of service.</t>
      <t>In order for these security guarantees to hold, several preconditions must be met:</t>
      <ol spacing="normal" type="1"><li>The client must be one of many users who might be using the proxy.  Otherwise, use of the proxy reveals the user's identity to the target.</li>
        <li>The client must hold an authentic KeyConfig for the target.  Otherwise, they could be speaking to the proxy, impersonating the target.</li>
        <li>All users of this proxy must be equally likely to use this URI and KeyConfig for this target, regardless of their prior activity.  Otherwise, the encrypted request identifies the user to the target.</li>
        <li>(optional) The target must not learn the IP addresses of the clients, collectively.  Otherwise, the target might be able to deanonymize requests by correlating them with external information about the clients.</li>
      </ol>
      <t>This specification defines behaviors for the client, proxy, and target that achieve preconditions 2-4.  (This specification does not address precondition 1.)</t>
      <t>This draft is an instantiation of the "Single Proxy Discovery" architecture for key consistency, defined in <xref section="4.2" sectionFormat="of" target="I-D.wood-key-consistency"/>.</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>
    </section>
    <section anchor="overview">
      <name>Overview</name>
      <t>In the Key Consistency Double-Check procedure, the Client emits two HTTP GET requests: one to the Proxy, and one through the Proxy to the Target.  The Proxy will forward the first request to the Target if the response is not in cache.</t>
      <figure>
        <name>Overview of Key-Consistency Double-Check</name>
        <artwork><![CDATA[
                +--------+       +-------+      +--------+
                |        |<=====>|       |<---->|        |
                | Client |       | Proxy |      | Target |
                |        |<====================>|        |
                +--------+       +-------+      +--------+
]]></artwork>
      </figure>
      <t>The proxy caches the response, ensuring that all clients share it during its freshness lifetime.  The client checks this against the authenticated response from the Target, preventing forgeries.</t>
    </section>
    <section anchor="requirements">
      <name>Requirements</name>
      <section anchor="oblivious-request-resource">
        <name>Oblivious Request Resource</name>
        <t>The Oblivious Request Resource <bcp14>MUST</bcp14> publish an Access Description <xref target="I-D.schwartz-masque-access-descriptions"/> containing the "ohttp.request" key, e.g.:</t>
        <sourcecode type="JSON"><![CDATA[
{
  "ohttp": {
    "request": {
      "uri": "https://example.com/ohttp/",
      "key": "(KeyConfig in Base64)"
    }
  }
}
]]></sourcecode>
        <t>This resource <bcp14>MUST</bcp14> be available over HTTP/3 <xref target="RFC9114"/>, so that it can be accessed via the proxy's CONNECT-UDP service (see <xref target="proxy"/>).</t>
        <t>The Oblivious Request Resource <bcp14>MUST</bcp14> include a "strong validator" ETag (<xref section="2" sectionFormat="of" target="RFC7232"/>) in any response to a GET request for this access description, and <bcp14>MUST</bcp14> support the "If-Match" HTTP request header (<xref section="3" sectionFormat="of" target="RFC7232"/>).  The response <bcp14>MUST</bcp14> indicate "Cache-Control: public, no-transform, s-maxage=(...), immutable" <xref target="RFC9111"/><xref target="RFC8246"/>.  For efficiency reasons, the max age <bcp14>SHOULD</bcp14> be at least 60 seconds, and preferably much longer.</t>
        <t>If this Access Description changes, and the resource receives a request whose "If-Match" header identifies a previously served version that has not yet expired, it <bcp14>MUST</bcp14> return a success response containing the previous version.  This response <bcp14>MAY</bcp14> indicate "Cache-Control: private".</t>
      </section>
      <section anchor="proxy">
        <name>Oblivious Proxy</name>
        <t>The Oblivious Proxy <bcp14>MUST</bcp14> publish an Access Description that includes the "ohttp.proxy" and "udp" keys, indicating support for CONNECT-UDP <xref target="I-D.ietf-masque-connect-udp"/>.  It <bcp14>SHOULD</bcp14> also contain the "dns" key, indicating support for DNS over HTTPS <xref target="RFC8484"/>, to enable the use of HTTPS records <xref target="SVCB"/> with CONNECT-UDP.</t>
        <figure>
          <name>Example Proxy Access Description</name>
          <sourcecode type="JSON"><![CDATA[
{
  "dns": {
    "template": "https://doh.example.com/dns-query{?dns}",
  },
  "udp": {
    "template":
        "https://proxy.example.org/masque{?target_host,target_port}"
  },
  "ohttp": {
    "proxy": {
      "template": "https://proxy.example.org/ohttp{?request_uri}"
    }
  }
}
]]></sourcecode>
        </figure>
        <t>The Oblivious Proxy Resources <bcp14>MUST</bcp14> allow use of the GET method to retrieve small JSON responses, and <bcp14>SHOULD</bcp14> make ample cache space available in order to avoid eviction of Access Descriptions.  The proxy <bcp14>SHOULD</bcp14> share cache state among all clients, to ensure that they use the same Access Descriptions for each Oblivious Request Resource.  If the cache must be partitioned for architectural or performance reasons, operators <bcp14>SHOULD</bcp14> keep the number of users in each partition as large as possible.</t>
        <t>Oblivious Proxies <bcp14>MUST</bcp14> preserve the ETag response header on cached responses, and <bcp14>MUST</bcp14> add an Age header (<xref section="5.1" sectionFormat="comma" target="RFC9111"/>) to all proxied responses.  Oblivious Proxies <bcp14>MUST</bcp14> respect the "Cache-Control: immutable" directive, and <bcp14>MUST NOT</bcp14> revalidate fresh immutable cache entries in response to any incoming requests.  (Note that this is different from the general recommendation in <xref section="2.1" sectionFormat="of" target="RFC8246"/>).  Oblivious Proxies also <bcp14>MUST NOT</bcp14> accept PUSH_PROMISE frames from the target.</t>
        <t>Proxies <bcp14>SHOULD</bcp14> employ defenses against malicious attempts to fill the cache.  Some possible defenses include:</t>
        <ul spacing="normal">
          <li>Rate-limiting each client's use of GET requests.</li>
          <li>Prioritizing preservation of cache entries that have been served to many clients, if eviction is required.</li>
        </ul>
        <t>Oblivious Proxies that are not intended for general-purpose proxy usage <bcp14>MAY</bcp14> impose strict transfer limits or rate limits on HTTP CONNECT and CONNECT-UDP usage.</t>
        <t>If the proxy offers a DNS over HTTPS resolver, it <bcp14>MUST NOT</bcp14> enable EDNS Client Subnet support <xref target="RFC7871"/>.</t>
      </section>
      <section anchor="client">
        <name>Client</name>
        <t>The Client is assumed to know an "https" URI of an Oblivious Request Resource's Access Description.  To use that Request Resource, it <bcp14>MUST</bcp14> perform the following "double-check" procedure:</t>
        <ol spacing="normal" type="1"><li>Send a GET request to the Oblivious Proxy's template (<tt>ohttp.proxy.template</tt>) with <tt>request_uri</tt> set to the Access Description URI.</li>
          <li>Record the response (A).</li>
          <li>Check that response A's "Cache-Control" values indicates "public" and "immutable".</li>
          <li>Establish a CONNECT-UDP tunnel through the proxy to the Access Description URI's origin.</li>
          <li>Fetch the Access Description URI through this tunnel, using a GET request with "If-Match" set to response A's ETag.</li>
          <li>Record the response (B).</li>
          <li>Check that responses A and B were successful and the contents are identical, otherwise fail.</li>
        </ol>
        <t>This procedure ensures that the Access Description is authentic and will be shared by all users of this proxy.  Once response A or B expires, the client <bcp14>MUST</bcp14> refresh it before continuing to use this Access Description, and <bcp14>MUST</bcp14> repeat the "double-check" process if either response changes.</t>
        <t>Clients <bcp14>MUST</bcp14> perform each fetch to the origin (step 4) as a fully isolated request.  Any state related to this origin (e.g. cached DNS records, CONNECT-UDP tunnels, QUIC transport state, TLS session tickets, HTTP cookies) <bcp14>MUST NOT</bcp14> be shared with prior or subsequent requests.</t>
      </section>
    </section>
    <section anchor="example-oblivious-doh">
      <name>Example: Oblivious DoH</name>
      <t>In this example, the client has been configured with an Oblivious DoH server and an Oblivious Proxy.  The Oblivious DoH server is identified by an Access Description at "https://doh.example.com/config.json" with the following contents:</t>
      <sourcecode type="JSON"><![CDATA[
{
  "dns": {
    "template": "https://doh.example.com/dns-query{?dns}",
  },
  "ohttp": {
    "request": {
      "uri": "https://example.com/ohttp/",
      "key": "(KeyConfig in Base64)"
    }
  }
}
]]></sourcecode>
      <t>The Oblivious Proxy is identified as "proxy.example.org", which implies an Access Description at "https://proxy.example.org/.well-known/access-services".  This resource's contents are:</t>
      <sourcecode type="JSON"><![CDATA[
{
  "dns": {
    "template": "https://proxy.example.org/dns-query{?dns}",
  },
  "udp": {
    "template":
        "https://proxy.example.org/masque{?target_host,target_port}"
  },
  "ohttp": {
    "proxy": {
      "template": "https://proxy.example.org/ohttp{?request_uri}"
    }
  }
}
]]></sourcecode>
      <t>The following exchanges then occur between the client and the proxy:</t>
      <artwork><![CDATA[
HEADERS
:method = GET
:scheme = https
:authority = proxy.example.org
:path = /ohttp?request_uri=https%3A%2F%2Fdoh.example.com%2Fconfig.json
accept: application/json

                              HEADERS
                              :status = 200
                              cache-control: public, immutable, \
                                  no-transform, s-maxage=86400
                              age: 80000
                              etag: ABCD1234
                              content-type: application/json
                              [Access Description contents here]

HEADERS
:method = CONNECT
:protocol = connect-udp
:scheme = https
:authority = proxy.example.org
:path = /masque?target_host=doh.example.com,target_port=443
capsule-protocol = ?1

                              HEADERS
                              :status = 200
                              capsule-protocol = ?1
]]></artwork>
      <t>The client now has a CONNECT-UDP tunnel to <tt>doh.example.com</tt>, over which it performs the following GET request using HTTP/3:</t>
      <artwork><![CDATA[
HEADERS
:method = GET
:scheme = https
:authority = doh.example.com
:path = /config.json
if-match = ABCD1234

                              HEADERS
                              :status = 200
                              cache-control: public, immutable, \
                                  no-transform, s-maxage=86400
                              etag: ABCD1234
                              content-type: application/json
                              [Access Description contents here]
]]></artwork>
      <t>Having successfully fetched the Access Description from both locations, the client confirms that:</t>
      <ul spacing="normal">
        <li>The responses are identical.</li>
        <li>The cache-control response from the proxy contained the "public" and "immutable" directives.</li>
      </ul>
      <t>The client can now use the KeyConfig in this Access Description to reach the Oblivious DoH server, by forming Binary HTTP requests for "https://doh.example.com/dns-query" and delivering the encapsulated requests to "https://example.com/ohttp/" via the proxy.</t>
    </section>
    <section anchor="performance-implications">
      <name>Performance Implications</name>
      <section anchor="latency">
        <name>Latency</name>
        <t>Suppose that the client-proxy Round-Trip Time (RTT) is <tt>A</tt>, and the proxy-target RTT is <tt>B</tt>.  Suppose additionally that the client has a persistent connection to the proxy that is already running.  Then the procedure described in <xref target="client"/> requires:</t>
        <ul spacing="normal">
          <li>
            <t><tt>A</tt> for the GET request to the proxy
            </t>
            <ul spacing="normal">
              <li>
                <tt>+B</tt> if the requested Access Description is not in cache</li>
              <li>
                <tt>+B</tt> if the proxy does not have a TLS session ticket for the target</li>
            </ul>
          </li>
          <li>
            <tt>A</tt> for the CONNECT-UDP request to the proxy</li>
          <li>
            <tt>A + B</tt> for the QUIC handshake to the target</li>
          <li>
            <tt>A + B</tt> for the GET request to the target</li>
        </ul>
        <t>This is a total of <tt>4A + 4B</tt> in the worst case.  However, clients can reduce the latency by issuing the requests to the proxy in parallel, and by using CONNECT-UDP's "false start" support.  The target can also optimize performance, by issuing long-lived TLS session tickets.  With these optimizations, the expected total time is <tt>2A + 2B</tt>.</t>
        <t>This procedure only needs to be repeated if the Access Description has expired.  Access Descriptions do not need to change frequently, so a cache lifetime of 1 day may be suitable.  Clients <bcp14>MAY</bcp14> perform this procedure in advance of an expiration to avoid a delay.</t>
      </section>
      <section anchor="thundering-herds">
        <name>Thundering Herds</name>
        <t>All clients of the same proxy and target will have locally cached Access Descriptions with the same expiration time.  When this entry expires, all active clients will send refresh GET requests to the proxy at their next request.  Proxies <bcp14>SHOULD</bcp14> use "request coalescing" to avoid duplicate cache-refresh requests to the target.</t>
        <t>If the Access Description has changed, these clients will initiate GET requests through the proxy to the target to double-check the new contents.  Proxies and targets <bcp14>MAY</bcp14> use an HTTP 503 response with a "Retry-After" header to manage load spikes.</t>
      </section>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <section anchor="in-scope">
        <name>In scope</name>
        <section anchor="forgery">
          <name>Forgery</name>
          <t>A malicious proxy could attempt to learn the contents of the oblivious request by forging an Access Description containing its own KeyConfig.  This is prevented by the client's requirement that the KeyConfig be served to it by the configured origin over HTTPS (<xref target="client"/>).</t>
        </section>
        <section anchor="deanonymization">
          <name>Deanonymization</name>
          <t>A malicious target could attempt to link multiple Oblivious HTTP requests together by issuing each user a unique, persistent KeyConfig.  This attack is prevented by the client's requirement that the KeyConfig be fresh according to the proxy's cache (<xref target="client"/>).</t>
          <t>A malicious target could attempt to rotate its entry in the proxy's cache in several ways:</t>
          <ul spacing="normal">
            <li>Using HTTP PUSH_PROMISE frames.  This attack is prevented by disabling PUSH_PROMISE at the proxy (<xref target="proxy"/>).</li>
            <li>
              <t>By also acting as a client and sending requests designed to replace the Access Description in the cache before it expires:
              </t>
              <ul spacing="normal">
                <li>By sending GET requests with a "Cache-Control: no-cache" or similar directive.  This is prevented by the response's "Cache-Control: public, immutable" directives, which are verified by the client (<xref target="client"/>), and by the proxy's obligation to to respect these directives strictly (<xref target="proxy"/>).</li>
                <li>By filling the cache with new entries, causing its previous Access Description to be evicted.  <xref target="proxy"/> describes some possible mitigations.</li>
              </ul>
            </li>
          </ul>
          <t>A malicious target could attempt to link different requests for the Access Description, in order to link the Oblivious HTTP requests that follow shortly after.  This is prevented by fully isolating each request (<xref target="client"/>), and by disabling EDNS Client Subnet (<xref target="proxy"/>).</t>
        </section>
        <section anchor="abusive-traffic">
          <name>Abusive traffic</name>
          <t>A malicious client could use the proxy to send abusive traffic to any destination on the internet.  Abuse concerns can be mitigated by imposing a rate limit at the proxy (<xref target="proxy"/>).</t>
        </section>
      </section>
      <section anchor="out-of-scope">
        <name>Out of scope</name>
        <t>This specification assumes that the client starts with identities of the proxy and target that are authentic and widely shared.  If these identities are inauthentic, or are unique to the user, then the security goals of this specification are not achieved.</t>
        <t>This specification assumes that at most a small fraction of clients are acting on behalf of a malicious target.  If a large fraction of the clients are malicious, they could conspire to flood the proxy cache with entries that seem popular, leading to rapid eviction of the malicious target's Access Descriptions.  Similar concerns apply if a malicious target can compel naive clients to fetch a very large number of Access Descriptions.</t>
      </section>
    </section>
    <section anchor="iana">
      <name>IANA Considerations</name>
      <t>No IANA action is requested.</t>
    </section>
  </middle>
  <back>
    <references>
      <name>References</name>
      <references>
        <name>Normative References</name>
        <reference anchor="I-D.ietf-ohai-ohttp">
          <front>
            <title>Oblivious HTTP</title>
            <author fullname="Martin Thomson">
              <organization>Mozilla</organization>
            </author>
            <author fullname="Christopher A. Wood">
              <organization>Cloudflare</organization>
            </author>
            <date day="15" month="February" year="2022"/>
            <abstract>
              <t>   This document describes a system for the forwarding of encrypted HTTP
   messages.  This allows a client to make multiple requests of a server
   without the server being able to link those requests to the client or
   to identify the requests as having come from the same client.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-ohai-ohttp-01"/>
        </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">
              <organization/>
            </author>
            <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">
              <organization/>
            </author>
            <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="I-D.schwartz-masque-access-descriptions">
          <front>
            <title>HTTP Access Service Description Objects</title>
            <author fullname="Benjamin M. Schwartz">
              <organization>Google LLC</organization>
            </author>
            <date day="7" month="April" year="2022"/>
            <abstract>
              <t>   HTTP proxies can operate several different kinds of access services.
   This specification provides a format for identifying a collection of
   such services.

About This Document

   This note is to be removed before publishing as an RFC.

   Status information for this document may be found at
   https://datatracker.ietf.org/doc/draft-schwartz-masque-access-
   descriptions/.

   Source for this draft and an issue tracker can be found at
   https://github.com/bemasc/access-services.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-schwartz-masque-access-descriptions-00"/>
        </reference>
        <reference anchor="RFC9114">
          <front>
            <title>HTTP/3</title>
            <author fullname="M. Bishop" initials="M." role="editor" surname="Bishop">
              <organization/>
            </author>
            <date month="June" year="2022"/>
            <abstract>
              <t>The QUIC transport protocol has several features that are desirable in a transport for HTTP, such as stream multiplexing, per-stream flow control, and low-latency connection establishment.  This document describes a mapping of HTTP semantics over QUIC.  This document also identifies HTTP/2 features that are subsumed by QUIC and describes how HTTP/2 extensions can be ported to HTTP/3.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9114"/>
          <seriesInfo name="DOI" value="10.17487/RFC9114"/>
        </reference>
        <reference anchor="RFC7232">
          <front>
            <title>Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests</title>
            <author fullname="R. Fielding" initials="R." role="editor" surname="Fielding">
              <organization/>
            </author>
            <author fullname="J. Reschke" initials="J." role="editor" surname="Reschke">
              <organization/>
            </author>
            <date month="June" year="2014"/>
            <abstract>
              <t>The Hypertext Transfer Protocol (HTTP) is a stateless application- level protocol for distributed, collaborative, hypertext information systems.  This document defines HTTP/1.1 conditional requests, including metadata header fields for indicating state changes, request header fields for making preconditions on such state, and rules for constructing the responses to a conditional request when one or more preconditions evaluate to false.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="7232"/>
          <seriesInfo name="DOI" value="10.17487/RFC7232"/>
        </reference>
        <reference anchor="RFC9111">
          <front>
            <title>HTTP Caching</title>
            <author fullname="R. Fielding" initials="R." role="editor" surname="Fielding">
              <organization/>
            </author>
            <author fullname="M. Nottingham" initials="M." role="editor" surname="Nottingham">
              <organization/>
            </author>
            <author fullname="J. Reschke" initials="J." role="editor" surname="Reschke">
              <organization/>
            </author>
            <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>
        <reference anchor="RFC8246">
          <front>
            <title>HTTP Immutable Responses</title>
            <author fullname="P. McManus" initials="P." surname="McManus">
              <organization/>
            </author>
            <date month="September" year="2017"/>
            <abstract>
              <t>The immutable HTTP response Cache-Control extension allows servers to identify resources that will not be updated during their freshness lifetime.  This ensures that a client never needs to revalidate a cached fresh resource to be certain it has not been modified.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8246"/>
          <seriesInfo name="DOI" value="10.17487/RFC8246"/>
        </reference>
        <reference anchor="I-D.ietf-masque-connect-udp">
          <front>
            <title>Proxying UDP in HTTP</title>
            <author fullname="David Schinazi">
              <organization>Google LLC</organization>
            </author>
            <date day="17" month="June" year="2022"/>
            <abstract>
              <t>   This document describes how to proxy UDP in HTTP, similar to how the
   HTTP CONNECT method allows proxying TCP in HTTP.  More specifically,
   this document defines a protocol that allows an HTTP client to create
   a tunnel for UDP communications through an HTTP server that acts as a
   proxy.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-masque-connect-udp-15"/>
        </reference>
        <reference anchor="RFC8484">
          <front>
            <title>DNS Queries over HTTPS (DoH)</title>
            <author fullname="P. Hoffman" initials="P." surname="Hoffman">
              <organization/>
            </author>
            <author fullname="P. McManus" initials="P." surname="McManus">
              <organization/>
            </author>
            <date month="October" year="2018"/>
            <abstract>
              <t>This document defines a protocol for sending DNS queries and getting DNS responses over HTTPS.  Each DNS query-response pair is mapped into an HTTP exchange.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8484"/>
          <seriesInfo name="DOI" value="10.17487/RFC8484"/>
        </reference>
        <reference anchor="RFC7871">
          <front>
            <title>Client Subnet in DNS Queries</title>
            <author fullname="C. Contavalli" initials="C." surname="Contavalli">
              <organization/>
            </author>
            <author fullname="W. van der Gaast" initials="W." surname="van der Gaast">
              <organization/>
            </author>
            <author fullname="D. Lawrence" initials="D." surname="Lawrence">
              <organization/>
            </author>
            <author fullname="W. Kumari" initials="W." surname="Kumari">
              <organization/>
            </author>
            <date month="May" year="2016"/>
            <abstract>
              <t>This document describes an Extension Mechanisms for DNS (EDNS0) option that is in active use to carry information about the network that originated a DNS query and the network for which the subsequent response can be cached.  Since it has some known operational and privacy shortcomings, a revision will be worked through the IETF for improvement.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="7871"/>
          <seriesInfo name="DOI" value="10.17487/RFC7871"/>
        </reference>
      </references>
      <references>
        <name>Informative References</name>
        <reference anchor="I-D.wood-key-consistency">
          <front>
            <title>Key Consistency and Discovery</title>
            <author fullname="Alex Davidson">
              <organization>Brave Software</organization>
            </author>
            <author fullname="Matthew Finkel">
              <organization>The Tor Project</organization>
            </author>
            <author fullname="Martin Thomson">
              <organization>Mozilla</organization>
            </author>
            <author fullname="Christopher A. Wood">
              <organization>Cloudflare</organization>
            </author>
            <date day="4" month="March" year="2022"/>
            <abstract>
              <t>   This document describes the key consistency and correctness
   requirements of protocols such as Privacy Pass, Oblivious DoH, and
   Oblivious HTTP for user privacy.  It discusses several mechanisms and
   proposals for enabling user privacy in varying threat models.  In
   concludes with discussion of open problems in this area.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-wood-key-consistency-02"/>
        </reference>
        <reference anchor="SVCB">
          <front>
            <title>Service binding and parameter specification via the DNS (DNS SVCB and HTTPS RRs)</title>
            <author fullname="Ben Schwartz">
              <organization>Google</organization>
            </author>
            <author fullname="Mike Bishop">
              <organization>Akamai Technologies</organization>
            </author>
            <author fullname="Erik Nygren">
              <organization>Akamai Technologies</organization>
            </author>
            <date day="24" month="May" year="2022"/>
            <abstract>
              <t>   This document specifies the "SVCB" and "HTTPS" DNS resource record
   (RR) types to facilitate the lookup of information needed to make
   connections to network services, such as for HTTP origins.  SVCB
   records allow a service to be provided from multiple alternative
   endpoints, each with associated parameters (such as transport
   protocol configuration and keys for encrypting the TLS ClientHello).
   They also enable aliasing of apex domains, which is not possible with
   CNAME.  The HTTPS RR is a variation of SVCB for use with HTTP [HTTP].
   By providing more information to the client before it attempts to
   establish a connection, these records offer potential benefits to
   both performance and privacy.

   TO BE REMOVED: This document is being collaborated on in Github at:
   https://github.com/MikeBishop/dns-alt-svc
   (https://github.com/MikeBishop/dns-alt-svc).  The most recent working
   version of the document, open issues, etc. should all be available
   there.  The authors (gratefully) accept pull requests.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-dnsop-svcb-https-10"/>
        </reference>
      </references>
    </references>
    <section numbered="false" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>TODO acknowledge.</t>
    </section>
  </back>
  <!-- ##markdown-source:
H4sIAAAAAAAAA+Vbe3PbRpL/H59ijq6tSAlJW7I2ybJW8VEPr3VnW1pJvq3U
3lY0BIbkrEAMFwNIZhTls9xnuU92/ZgZDEDIzj6q9qpWlQcJzrOn+9e/7mmM
RqOk0lWuJmLwn2ojjk1hta1UkW7E3JTifJbrO21qK95cX1+I2UacmHqWq9Hx
UqW3ulgMEjmblequpz+3FNRykKSyUgtTbibCVlmSZCYt5AqmzUo5r0Y2Xd7L
svpxZJZSj9JmlFFGo6Q4yOjFXgITvUxkqSSMo9Lk3pS3i9LU64nAnsmt2sCj
bCLOikqVhapGJzh+cqeKWk0SIRa6WtYzWO1MraRNn8s0VdaOrCrvNHwaJIms
q6Upoe0Imgsxr/OcV3qkij/LlS7Eu7G4cuulJqZcyEL/KCttion4nTEL2Pbb
t8f0I0yj84ng6f59QT+OU7NKksKUK+hzB+tKdDGPviWj0UjIma1KmVZJcr1U
Qlpbl7KAJYp1ae50pjI8jc75ZGqtikyYQlTQJ821KqovLAylc11tRGXEnSr1
HD4tZSU0/GNFbeEYqb2FbYpL9Zda2Qr+b01dpjAzDAhHCyc71wtYh1jJYiMM
dCihryrtWIjrJQxk1yrVc52SHGApc13AaiWutzKpyXF6VUjUiQrb01Jc8zHv
eaWzLFdJ8gzPrzRZneKPSdLZ5sPDv52NTsZaVXNWGLOsqvXjI0ylbL3CWSuR
KwnbqJalUmINZ6XhMa5ApkuhPqZLWSzgUBs5DekzLPbjZkibxq+VLBeqEjt0
Onm+4UbNcrrS2gVh/GGpCpRMhoOtVYm9OhtgMdhodlyaxbMreURaa7QCUDtb
w8qluJfu+KJfU1kUBp6oPBf3S0VnU92bZrAUj3ZemlVz0G5ev1PauB/IKsVr
M2BGBfQ3c/ruxxt3j+QLS5KGVa1MpnJS1xVtEB6FwzCF8iPxdB0xg1KAwqM6
NpLTYzWGdazW+QZ/uAf79QOwVuEYt0qt8ddUlZUEUQVzAkVMUXEz2IWWOZzO
2VwoTQLiJQDIudlX2s7UUt4py6dsinwj1HyuUvithuXPwBhArwsYCLfhMANk
cVbAMBkMiZAJXa1CcKpLtLlFLcFuK8XatzR5NoQfQfdhEFBXWF2mcZ02zLFS
FWDA3lhcN9rhf3MSJBMk44PjNrDyxZJ+bmyZNgfbPcet3murhti+LX2AbSVz
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

-->

</rfc>
