jiebi/TextFlow huggingface dataset:
Original text:
A proxy MUST NOT add information about the client identity when forwarding requests.  This includes the Via field, the Forwarded <del> field FORWARDED, and any similar information. </del>  8.2.1.

Reviewer comments:
But they should. Consider the case where clients have equal-sized messages, but are making requests using different key identifiers or different request targets. If that information could be linked to certain clients, encryption would increase the size of the anonymity set from the perspective of a passive observer for little extra cost.
Done. PTAL.
Clients and proxies create independent TLS connections to the upstream node in the OHTTP chain. This raises some interesting questions: What if the trust stores between client and proxy are disjoint? What if the proxy completely disables server authentication in its connection to the target? The does not assume a secure connection between proxy and target, so I don't think this has an effect on the security properties of OHTTP. That said, it may be worth noting explicitly, if we don't already do so.
Yeah, the same applies here. We rely on the proxy not leaking certain information, but that does not necessarily extend to a reliance on TLS for that hop. Worth noting.

Revised text:
A proxy MUST NOT add information about the client identity when forwarding requests.  This includes the Via field, the Forwarded  <ins> field FORWARDED, and any similar information.  A client does not depend on the proxy using an authenticated and encrypted connection to the oblivious request resource, only that information about the client not be attached to forwarded requests. </ins> 8.2.1.
Original text:
10.  Please update the "Media Types" registry at https://www.iana.org/assignments/media-types [1] with the registration information in media-types for the media types "message/ ohttp-req", "message/ohttp-res", and "application/ohttp-keys". <del> 11.  References </del>  <del> 11.1.  URIs </del>  [1] https://www.iana.org/assignments/media-types

Reviewer comments:
I wanted to add more then just interception text here. So I added a little about performance and the ODoH study made some of those costs clear enough to cite. I anticipate this section growing over time. Some of the material we might add is already in other sections of the doc (DoS management at the proxy, for example), but we might move that around some. I also expect the working group to focus rather narrowly on this topic. Let's leave this open so that we have something to point to for IETF discussions.

Revised text:
10. <ins> Using Oblivious HTTP adds both cryptographic and latency to requests relative to a simple HTTP request-response exchange.  Deploying proxy services that are on path between clients and servers avoids adding significant additional delay due to network topology.  A study of a similar system ODoH found that deploying proxies close to servers was most effective in minimizing additional latency. Oblivious HTTP might be incompatible with network interception regimes, such as those that rely on configuring clients with trust anchors and intercepting TLS connections.  While TLS might be intercepted successfully, interception middleboxes devices might not receive updates that would allow Oblivious HTTP to be correctly identified using the media types defined in media-types. Oblivious HTTP has a simple key management design that is not trivially altered to enable interception by intermediaries.  Clients that are configured to enable interception might choose to disable Oblivious HTTP in order to ensure that content is accessible to middleboxes. 11. </ins> Please update the "Media Types" registry at https://www.iana.org/assignments/media-types [1] with the registration information in media-types for the media types "message/ ohttp-req", "message/ohttp-res", and "application/ohttp-keys".  <ins> 12.  References </ins>  <ins> 12.1.  URIs </ins> [1] https://www.iana.org/assignments/media-types
Original text:
authenticated so that it can be attributed to the oblivious request resource; see key-configuration.  Clients MUST NOT include identifying information in the request that is encapsulated.  Identifying information includes cookies COOKIES, authentication credentials or tokens, and any information that might

Reviewer comments:
This may not be obvious, so perhaps good to note.
I'll move most of the text to the client section, leaving a pointer in the proxy section.
It probably depends. One could fetch the HPKE key and apply policy for each OHTTP message, which would be equivalent to applying policy for each HTTP connection if you were not using OHTTP, or one could fetch and apply policy to the HPKE key for many OHTTP messages. The results are different.
NAME this should be good to go.
Thanks for changing it up. I'm not 100% on the structure of this yet, but it is more important to get the info in place.

Revised text:
authenticated so that it can be attributed to the oblivious request resource; see key-configuration. <ins> Since clients connect directly to the proxy instead of the target, application configurations wherein clients make policy decisions about target connections, e.g., to apply certificate pinning, are incompatible with Oblivious HTTP.  In such cases, alternative technologies such as HTTP CONNECT (Section 9.3.6 of HTTP) can be used.  Applications could implement related policies on key configurations and proxy connections, though these might not provide the same properties as policies enforced directly on target connections.  When this difference is relevant, applications can instead connect directly to the target at the cost of either privacy or performance. </ins> Clients MUST NOT include identifying information in the request that is encapsulated.  Identifying information includes cookies COOKIES, authentication credentials or tokens, and any information that might
Original text:
5. HTTP message encapsulation uses HPKE for request and response <del> encryption.  An encapsulated HTTP message includes the following values: A binary-encoded HTTP message; see BINARY. Padding of arbitrary length which MUST contain all zeroes. The encoding of an HTTP message is as follows: </del>  An Encapsulated Request is comprised of a length-prefixed key identifier and a HPKE-protected request message.  HPKE protection response, which might not be what some clients want. A proxy can use padding to reduce the effectiveness of traffic <del> analysis. </del>  A proxy that forwards large volumes of exchanges can provide better privacy by providing larger sets of messages that need to be matched.

Reviewer comments:
See discussion on-list.
See also URL
If we're pinning the contents of the encapsulation to message/bhttp, it seems like we also ought to change the HPKE info strings to match ("request" -> "message/bhttp-request" or whatever). When someone tries to reuse this layer of encapsulation, I think they ought to change the info string accordingly to match whatever the underlying type is. And it might not hurt to add guidance to such people in the security considerations. Can we do this in a followup PR?
I agree that we should think about content types a bit more, but that seems appropriate for another PR.
With , we're enforcing a 1:1 mapping between message/ohttp-req and message/bhttp, but we don't have any cryptographic enforcement of this pairing. If someone were to reuse the encapsulation mechanism in this document with another message type, say, to encapsulate application/dns-message values with a application/oblivious-dns-message wrapper, then we'd probably want to ensure that targets can't get confused between these two types. We could use the HPKE info string to separate these two protocols. (This is related to .)
The format I've sketched out for binary messages can be padded with zeros without needing a separate padding field. That's probably a feature worth mentioning in both drafts.
Padding is in the binary HTTP draft now.

Revised text:
5. HTTP message encapsulation uses HPKE for request and response  <ins> encryption.  An encapsulated HTTP message includes a binary-encoded HTTP message and no other content; see BINARY. </ins> An Encapsulated Request is comprised of a length-prefixed key identifier and a HPKE-protected request message.  HPKE protection response, which might not be what some clients want. A proxy can use padding to reduce the effectiveness of traffic  <ins> analysis.  Padding is a capability provided by binary HTTP messages; see Section 3.8 of BINARY. </ins> A proxy that forwards large volumes of exchanges can provide better privacy by providing larger sets of messages that need to be matched.
Original text:
The client then constructs an encapsulated request, "enc_request", as follows: <del> Compute an HPKE context using "pkR", yielding "context" and encapsulation key "enc". </del>  Construct associated data, "aad", by concatenating the values of "keyID", "kemID", "kdfID", and "aeadID", as one 8-bit integer and that the server is unwilling to use with "skR", the server returns an error. <del> Compute an HPKE context using "skR" and the encapsulated key "enc", yielding "context". </del>  Construct additional associated data, "aad", from "keyID", "kemID", "kdfID", and "aeadID" or as the first seven bytes of response "response", servers generate an Encapsulated Response "enc_response" as follows: <del> Export a secret "secret" from "context", using the string "response" as context.  The length of this secret is "max(Nn, Nk)", where "Nn" and "Nk" are the length of AEAD key and nonce </del>  associated with "context". Generate a random value of length "max(Nn, Nk)" bytes, called corresponds to the key identifier, but the encapsulated request cannot be successfully decrypted using the key.  8.4. Encapsulated requests can be copied and replayed by the oblivious

Reviewer comments:
This is a breaking change, but I think that it's worthwhile. "request" is an extraordinary generic string and the risk of it being used in another context is too high.
We can address test vectors in a followup PR.

Revised text:
The client then constructs an encapsulated request, "enc_request", as follows:  <ins> Compute an HPKE context using "pkR" and a label of "ohttp request", yielding "context" and encapsulation key "enc". </ins> Construct associated data, "aad", by concatenating the values of "keyID", "kemID", "kdfID", and "aeadID", as one 8-bit integer and that the server is unwilling to use with "skR", the server returns an error.  <ins> Compute an HPKE context using "skR", a label of "ohttp request", and the encapsulated key "enc", yielding "context". </ins> Construct additional associated data, "aad", from "keyID", "kemID", "kdfID", and "aeadID" or as the first seven bytes of response "response", servers generate an Encapsulated Response "enc_response" as follows:  <ins> Export a secret "secret" from "context", using the string "ohttp response" as context.  The length of this secret is "max(Nn, Nk)", where "Nn" and "Nk" are the length of AEAD key and nonce </ins> associated with "context". Generate a random value of length "max(Nn, Nk)" bytes, called corresponds to the key identifier, but the encapsulated request cannot be successfully decrypted using the key. <ins> A server MUST ensure that the HPKE keys it uses are not valid for any other protocol that uses HPKE with the "ohttp request" label. Designers of other protocols, especially new versions of this protocol, can ensure key diversity by choosing a different label in their use of HPKE.  The "ohttp response" label was chosen for symmetry only as it provides key diversity only within the HPKE context created using the "ohttp request" label. </ins> 8.4. Encapsulated requests can be copied and replayed by the oblivious
Original text:
key configurations is not included in this specification.  Clients need to consider these tracking vectors when choosing a discovery method.  Applications using this design should provide accommodations <del> to mitigate tracking using key configurations. </del>  10.

Reviewer comments:
What do we want to do with this draft? Should we dispatch it and find it a home?
Good question. I wonder if secdispatch would be a good place to ask.
Clients should cache server keys for some time. TTL can be supply in a cache-control header of a ohttp-keys response. Should this be mentioned or is it implied?
The document doesn't really define the key configuration acquisition method, so it can't really cover details like caching (or retention). Getting into specifics with HTTP Cache-Control is out of scope. There is discussion of retention periods in , which are relevant and might be worth pointing to. That document has uncertain status, but we might still use an informative reference.

Revised text:
key configurations is not included in this specification.  Clients need to consider these tracking vectors when choosing a discovery method.  Applications using this design should provide accommodations  <ins> to mitigate tracking using key configurations.  CONSISTENCY provides an analysis of the options for ensuring the key configurations are consistent between different clients. </ins> 10.
Original text:
their usage to their developers might use oblivious HTTP for some types of moderately sensitive data.  4. A client needs to acquire information about the key configuration of

Reviewer comments:
For and NAME
I recognize that / added some conditions and use cases, but it would help readers like me to have even more. A separate explainer document/readme would be fine too. In the meeting chat today, I heard the suggestion of requesting map tiles as another use case, which makes sense to me: asking for map tiles is itself pretty revealing if connected to the user's identity (it might reveal your current location, or a location where you're going to be) and can be pretty transactional/stateless. Maybe search queries are similar. Safe browsing lookups was also mentioned. Having more example use cases might help in resolving other questions, like whether to support multiple HTTP requests at a time, or non-HTTP message bodies, etc. Ideally, we could explain the conditions under which adoption of ohttp will be useful -- maybe, a privacy need for reducing linkability of multiple requests or of a single request from user identity, and HTTP requests that are typically stateless or single-shot in some way, and frequent or performant-requiring at a certain level.
NAME added some more examples. NAME I think we can safely close this now, so I'm going to go ahead and do that. Please reopen with concrete suggestions if you think the new text is insufficient!

Revised text:
their usage to their developers might use oblivious HTTP for some types of moderately sensitive data. <ins> These are examples of requests where there is information in a request that - if it were connected to the identity of the user - might allow a server to learn something about that user even if the identity of the user is pseudonymous.  Other examples include the submission of anonymous surveys, making search queries, or requesting location-specific content (such as retrieving tiles of a map display). </ins> 4. A client needs to acquire information about the key configuration of
Original text:
on-path devices that a flow has ended is that packets are no longer observed.  Stateful devices on path such as NATs and firewalls must therefore use idle timeouts to determine when to drop state for QUIC <del> flows. </del>  3.6. either through timers or through least-recently-used eviction, depending on application requirements.  The QUIC header optionally contains a Connection ID which can be used as additional entropy beyond the 5-tuple, if needed.  The QUIC handshake needs to be observed in order to understand whether the

Reviewer comments:
But how long...?
For discussion: should the manageability draft advise that idle timeouts should be longer for flows inferred/detected to be QUIC flows? I think the answer here is "it depends": for NATs, yes, state at the edge is not all that scarce anymore. For firewalls? Maybe not so much. Are there other applications to consider here, and is there any generalized advice this document could give? If so, is there any generalized advice for how long the timeout should be?
PR is an attempt to address this issue but doesn't provide much concrete guidance...

Revised text:
on-path devices that a flow has ended is that packets are no longer observed.  Stateful devices on path such as NATs and firewalls must therefore use idle timeouts to determine when to drop state for QUIC  <ins> flows, see further section sec-stateful. </ins> 3.6. either through timers or through least-recently-used eviction, depending on application requirements. <ins> RFC4787 recommends a 2 minute timeout interval for UDP, however, often timer are lower in the range of 15 to 30 second.  In constrast RFC5382 recommends a timeout of more than 2 hours for TCP, given TCP is a connection-oriented protocol with well defined closure semantics.  For network devices that are QUIC-aware, it is recommended to also use longer timeouts for QUIC traffic, as QUIC is connection-oriented and as such a handshake packet from the server indicates the willingness of the server to communicate with the client. </ins> The QUIC header optionally contains a Connection ID which can be used as additional entropy beyond the 5-tuple, if needed.  The QUIC handshake needs to be observed in order to understand whether the
Original text:
balancers that forward the traffic based on the Connection ID.  A server can choose the Connection ID in the Server Retry packet such that the load balancer will redirect the next Client Initial packet <del> to a different server in that pool. </del>  10.

Reviewer comments:
References to quic-load-balancers and RFC5077 (due to lack of a better reference) added
I thought the plan was to have a dependency on the load balancing draft rather than merging this part into the applicability draft. However, I would also be fine to add more text here and only have an informational reference, if some is willing to provide text!
... in the applicability statement? I mean one example mechanism maybe...
Can anybody help with that?
URL
The 5077 construction is pretty outdated (it's not even AEAD), unfortunately.
NAME is there somewhere else we should look for current best practice, or do we need to invent something new here?
I'll find a stuckee for up-to-date crypto language here at the Zurich interim.
closing for now, couldn't find any takers.
...actually, it's in the LB draft. Reference it.
PR proposed to address this issue...
Are you prepared to take a dependency on QUIC-LB?

Revised text:
balancers that forward the traffic based on the Connection ID.  A server can choose the Connection ID in the Server Retry packet such that the load balancer will redirect the next Client Initial packet  <ins> to a different server in that pool.  Alternatively the load balancer can directly offer a Retry services as further described in QUIC-LB. RFC5077 Section 4 describes an example approach for constructing TLS resumption tickets that can be also applied for validation tokens, however, the use of more modern cryptographic algorithms is highly recommended. </ins> 10.
Original text:
attack vector on specific servers or pools. The best way to obscure an encoding is to appear random to observers, <del> which is most rigorously achieved with encryption. </del>  9.2.

Reviewer comments:
…ancers for further algos
The intention was not to encrypt the length (as you say that would not be helpful) but you should probably "grease" the length such that those bit can not be used to identify a certain system. That was the intention here. However, maybe this is too much detail and we should remove that sentence and only refer to the load-balancer draft instead...?
Note in section about CID that as the server chooses the CIDs, it could use some own scheme to embed the length of the CID in the CID itself, instead remembering it, e.g. use the first few bits to indicate which of the sizes that are support was chosen.
can be done together with , referencing the LB draft
PR to address this and reference to load balancer draft
Reading this again, I'm not sure how I would improve the phrasing. Perhaps "embed the length of the connection ID in plaintext ...".

Revised text:
attack vector on specific servers or pools. The best way to obscure an encoding is to appear random to observers,  <ins> which is most rigorously achieved with encryption.  Even when encrypted, a scheme could embed the unencrypted length of the Connection ID in the Connection ID itself, instead of remembering it, e.g. by using the first few bits to indicate a certain size of a well-known set of possible sizes with multiple values that indicate the same size but are selected randomly. QUIC_LB further specified possible algorithms to generate Connection IDs at load balancers. </ins> 9.2.
Original text:
location of fields used in the version negotiation process is invariant QUIC-INVARIANTS. <del> This document is focused on the protocol as presently defined in QUIC-TRANSPORT and QUIC-TLS.  Non-invariant parts of the wire image as described herein and in those documents cannot be used to identify QUIC as a protocol, and cannot be relied upon to infer behavior of future versions of QUIC. </del>  2.1.

Reviewer comments:
It might be the case that this is true for the whole draft and we should just state this at the beginning but better to double-check!
we will leave this issue open to double-check at the end

Revised text:
location of fields used in the version negotiation process is invariant QUIC-INVARIANTS.  <ins> This document describes only version 1 the QUIC protocol, whose wire image is fully defined in QUIC-TRANSPORT and QUIC-TLS.  Note that features of the wire image described herein and in those documents may change in future versions of the protocol, and cannot be used to identify QUIC as a protocol or to infer the behavior of future versions of QUIC. sec-google-version provides non-normative guidance on the identification of QUIC version 1 packets compared to other deployed versions at the date if publication. </ins> 2.1.
Original text:
Streams can be unidirectional or bidirectional, and a stream may be initiated either by client or server.  Only the initiator of a <del> unidirectional stream can send data on it.  Due to offset encoding limitations, a stream can carry a maximum of 2^62-1 bytes in each direction.  In the presently unlikely event that this limit is reached by an application, the stream can simply be closed and replaced with a new one. </del>  Streams can be independently opened and closed, gracefully or by error.  An application can gracefully close the egress direction of a

Reviewer comments:
This text in is incorrect. When you have sent that much data, the connection flow control limit cannot be increased further. Consequently, though many additional streams can be opened when a stream hits this limit, you cannot send any bytes on any of those streams. I recommend striking this sentence or replacing it with a note about this fundamental limit applying to all data conveyed in streams.
Happy to take a PR :-)
Pretty good. Thanks.

Revised text:
Streams can be unidirectional or bidirectional, and a stream may be initiated either by client or server.  Only the initiator of a  <ins> unidirectional stream can send data on it. Due to encoding limitations on stream offsets and connection flow control limits, both streams and connections can carry a maximum of 2^62-1 bytes in each direction.  In the presently unlikely event that this limit is reached by an application, a new connection would need to be established. </ins> Streams can be independently opened and closed, gracefully or by error.  An application can gracefully close the egress direction of a