Early Review of draft-ietf-rats-coserv-07
review-ietf-rats-coserv-07-httpdir-early-pardue-2026-08-14-00
| Request | Review of | draft-ietf-rats-coserv |
|---|---|---|
| Requested revision | No specific revision (document currently at 07) | |
| Type | Early Review | |
| Team | HTTP Directorate (httpdir) | |
| Deadline | 2026-07-31 | |
| Requested | 2026-06-29 | |
| Requested by | Mike Bishop | |
| Authors | Paul Howard , Thomas Fossati , Henk Birkholz , Shefali Kamal , Giridhar Mandyam , Ding Ma | |
| I-D last updated | 2026-07-22 (Latest revision 2026-07-06) | |
| Completed reviews |
Httpdir Early review of -07
by Lucas Pardue
|
|
| Comments |
Per request from RATS chairs |
|
| Assignment | Reviewer | Lucas Pardue |
| State | Completed | |
| Request | Early review on draft-ietf-rats-coserv by HTTP Directorate Assigned | |
| Reviewed revision | 07 | |
| Result | Not ready | |
| Completed | 2026-08-14 |
review-ietf-rats-coserv-07-httpdir-early-pardue-2026-08-14-00
The document defines a query/response format named CoSERV that operates with the RATS architecture. In addition, a concrete "API binding" describes how HTTP can be used to transfer the CoSERV query and response. This binding pays special attention to request format and its role in HTTP caching, which appears to address operation performance goals. A CoSERV query is serialized into a URI using a well defined mechanism and sent in an HTTP request; a CoSERV response is serialized in a new media type that is sent as response content. The document also defines a discovery mechanism based on /.well-known. I apologise for posting the review later than the deadline (2026-07-31). I wanted to ensure I could give a thorough review. Having now completed that, I feel obliged to record a "Not Ready" result. There are some fundamental issues related to caching that raise questions that likely need to be answered by the WG/authors. I do not think these issues are _that_ complicated but resolving them now will help avoid future interop issues (especially within the HTTP ecosystem that the design seems to want to leverage). I have no background knowledge of RATS and so have focused the httpdir review on HTTP topics, and only touched the RATS / CoSERV aspects needed to facilitate understanding the HTTP parts. Therefore, I may have misunderstood something at that layer. I am also not an HTTP caching expert, so have reviewed those aspects only to the best of my capability. To complete this review, I performed a manual review, combined with an automated review based on tooling in the repo https://github.com/mnot/ietf-skill, and Claude to assist with background, research, and cross referencing. I have checked and validated the review outcome to the best of my ability. All text in this review report has been manually generated based on the above and may still have mistakes. # Major issues 1. Privacy concerns of the caching design wrt HTTP caching IIUC this topic has been discussed in the WG. However, I think the current text, in combination with fundamental design choices wrt HTTP caching, leaves a potential adjacent privacy issue. A CoSERV query is serialized into a URI using a well defined, **deterministic** mechanism and sent in an HTTP request e.g. GET /coserv/{base64url-encoded-string}. The protocol expects this URI to be used as a cache key. The data that forms the input to the CoSERV query can contain sensitive information for a small anonymity set. In my simplified comprehension of RATS terms, an `instance` can identify a single unique device or component, while a `group` is a group whose anonymity is only as good as its size. While the document addresses some of this topic in RATS terms, the use of generic HTTP caching, IIUC, introduces some potential new threats. The HTTP cache itself can become an oracle; the timing of serving responses can indicate if someone has already queried the information. An attack could come in the form of scraping a list of predictable identifiers (correlating to a deterministic URI) to gain intel on instances or groups based on the performance of HTTP results. A generic HTTP cache makes itself available to any generic client to perform such an attack. The AI tooling suggests that this has been touched on in issue 81 and 67. However, the text following text in the document is likely insufficient to address the oracle problem: > Although reusing cached responses is generally desirable, clients that need to > bypass the caching infrastructure can do so by specifying Cache-Control: > no-cache in their requests. This cache control directive affects one aspect, skipping any cached value and going to origin. However, that doesn't prevent the issue. The result of the no-cache request **can be stored in the cache**. Its unclear to me if the authors meant to specify the usage of the **no-store** directive. Importantly, other clients can do other things; if they can probe a shared cache with private info, a side channel exists. A possible improvement is to lean on HTTP's toolkit more. The "private" directive might be appropriate for very-fine-grained information in the query such as instance or group. This would stop caching for those queries while allowing broader queries to benefit. If the WG/authors agree this oracle is an issue but cannot find consensus on a standard mitigation, then security consideration text that highlights the threats and HTTP toolkit might be sufficient. Sometimes its really up to deployments to decide on the privacy/performance tradeoff. The important thing is the ensure no naive use of shared caching; an "off-the-shelf" caching HTTP server might just do that. 2. Safe methods and HEAD The document states "only safe HTTP methods are used" and goes on to specify how GET is used to make queries. But this is not an s/methods/method editorial-level matter. RFC 9110 states "All general-purpose servers MUST support the methods GET and HEAD. All other methods are OPTIONAL.". This document is silent on HEAD, which is problematic. HEAD is functionally equivalent to GET ("SHOULD send the same header fields in response to a HEAD request as it would have sent if the request method had been GET), implying that a CoSERV server would run the same processing as the GET request. Is that desirable? There's also some deeper consideration to make wrt caching. Various freshness validators _could_ be used with GET. However, RFC 9111 Section 4.3.5 states how HEAD requests interact with caching in the absence of conditional GET. This issue is somewhat elevated by the lack of explicit guidance on validators, see (3). For the purposes of CoSERV, it may be appropriate to disallow HEAD. This would prevent clients from having a cheap way to trigger work on the server (i.e. a low-bandwidth CPU amplification attack). Safe methods can be trivially replayed and things like 0-RTT early data could make a server more liable to attack. 4. Query size bounds, URI privacy and QUERY method This is probably going to be one of the more controversial comments. The CoSERV HTTP binding requires converting a query into a base64url string carried in the URI. I don't know how big the underlying query data tends to be in practice but the HTTP ecosystem does tend to limit the size of URI they support. IIUC query size is unbounded but there may be real practical limits to sending them via HTTP. The recently published QUERY method (RFC 10008) summarizes the potential problems quite well: > when the data conveyed is too voluminous to be encoded in the request's URI, this pattern becomes problematic: > * size limits often are not known ahead of time because a request can pass through many uncoordinated systems (but note that Section 4.1 of [HTTP] recommends senders and recipients to support at least 8000 octets), > * expressing certain kinds of data in the target URI is inefficient because of the overhead of encoding that data into a valid URI, > * request URIs are more likely to be logged than request content and may also turn up in bookmarks, The simplest thing to do is consider adding some text to highlight the potential failure mode. A 414 (URI too Long) mention might be useful. You may also want to highlight the privacy issues with logging URIs that contain any potential PII. Possibly unpalatable: consider adding/substituting support for QUERY. This would allow you to have a safe method to send the query in a more efficient binary representation. A valid reason not to adopt QUERY wholesale at this time is that support is still rolling out. A future binding might want to consider it though, especially if you need larger queries and bump into limits. 3. Validators and ETags The document is quite quiet on conditional GETs. Perhaps thats ok since it things might "just work". However, the document does mention use of ETags in an example. And as presented, the example is both invalid and raises some questions. The AI was very concerned about the **determinism of the response** (in contrast to the determinism of the request). While RFC 9110 describes its the origin servers prerogative to calculate ETags however they like, this doc might have to do more. The AI raised the requirement in section 3.5 "Result sets always include a timestamp indicating the expiry time of the entire result set." and highlighted that results are signed via COSE (section 4.6) which may not be byte-for-byte identical unless the server uses RFC 6979. I am not qualified to comment authoritatively on these aspects of the payload. However, RFC 9110 section 8.8.1 does have text on this type of thing. The document might want to consider spec'ing the use of weak validators if that's a better representation of the information. SCIM appears to have had to do so. Strong validators based on a hash of the content might cause all conditional requests to fail, which would defeat the caching purposes of this protocol. More specifically on ETags, the examples that use them are invalid - the origin should be the ones generating them. 5. Freshness This one is borderline minor. The document attempts to align CoSERV result "embedded freshness" with HTTP freshness and provides a recommendation: > the origin server MUST NOT set HTTP cache directives (e.g. Cache-Control: > max-age, Expires) such that the freshness lifetime of the HTTP response > exceeds the result set expiry timestamp contained within the CoSERV results. That's good, but an origin might not set any Cache-Control directive in responses. That could trigger an HTTP cache to use its own heuristics for deciding on the cache freshness; see RFC 9111 section 4.2.2: > Since origin servers do not always provide explicit expiration times, a cache > MAY assign a heuristic expiration time when an explicit time is not specified, > employing algorithms that use other field values (such as the Last-Modified > time) to estimate a plausible expiration time. This specification does not > provide specific algorithms, but it does impose worst-case constraints on > their results. The document might want to highlight the possibility for such an origin to behave this way, even if there's not much that can be done to make genric HTTP caches deal with it. # Minor issues 6. Discovery content negotiation and response caching It seems #94 was not properly resolved. There was a comment "I think we need to say that servers MUST support both formats" but no text was actually added to do it. Leading on from that, the discovery document has two formats, JSON or CBOR. By default, the responses for these objects is going to be cachable too. However, the spec doesn't mention it. For scalability, I suspect you might want to embrace it. If so, consider adding text about the `Vary: Accept` field in the origin's response to ensure that a HTTP cache doesn't accidentally serve a different type than a client might expect. 7. Accept looseness The document levies some requirements on the Accept header: > If the client presents any media type other than these two options in its HTTP > Accept header, the implementation SHOULD respond with an HTTP 406 (Not > Acceptable) status code RFC 9110 section 12.4.1 has some text too: > For each of the content negotiation fields, a request that does not contain > the field implies that the sender has no preference on that dimension of > negotiation. > If a content negotiation header field is present in a request and none of the > available representations for the response can be considered acceptable > according to it, the origin server can either honor the header field by > sending a 406 (Not Acceptable) response or disregard the header field by > treating the response as if it is not subject to content negotiation for that > request header field. This does not imply, however, that the client will be > able to use the representation. I'm not sure if this spec is trying to be stricter than RFC 9110 or not. This probably needs tightening up with a MUST, or just defer to RFC 9110 if it doesn't matter much. 8. Error Content-Type broadness The doc states: > For error responses (4xx or 5xx status codes), the Content-Type header field > MUST be application/concise-problem-details+cbor... containing [title, > detail]. This is a bit broad because HTTP layered. the CoSERV app is running atop lower-layer HTTP things, which could generate their own errors. It's more correct to state something along the liens that a CoSERVER MUST send application/concise-problem-details+cbor... content when returning error responses (including the useful details like content-type and fields etc). That accomodates for a client seeing any kind of error status with any content (or none at all), that might be generated in an Internet deployment. 9. Rate limiting There is an example about ratelimiting. I'm not sure it fits this document well. Its possible that a layer beneath CoSERV could be implementing the rate limiting, yet this example seems to imply its the CoSERV server? The use of 429 overlaps a bit with issue 7. What should a client expect to do with a rate limiting response, especially if it isn't the application/concise-problem-details+cbor you're mandating at the CoSERV level. The document might want to nix the example and instead describe the possibility of rate limiting in the binding or security consideration sections. HTTP ratelimiting is also evolving, using one very specific example might lead people up the garden path. If you want to keep this, the "MAY" is an issue and should be rephrased. 10. Truncated examples The request examples have truncated URIs such as "/coserv/ogB4I3R...". Given how important these are to the whole caching story it would be really useful to have a fully worked value in the document somewhere. Even if the examples use a short-hand for presentation. 11. Redirects There is no definition of how redirects are to be handled. This seems problematic given that there seems to be some expectation that the URI is closely related the response content. 12. Inconsistent discovery responses Section 6.1.2.3 has examples. The requests are to the same /.well-known endpoint and vary only by the Accept header. However, the AI suggests the "result-verification-key" doesn't match. This contrasts with other normative text that states the responses should be equivalent apart from the serialization. 13. Caching examples and time The AI states the examples in 6.1.4.2 misuse HTTP fields. Its worth double checking this once the ETag stuff is decided upon. RFC 9111 states > When a stored response is used to satisfy a request without validation, a > cache MUST generate an Age header field (Section 5.1), replacing any present > in the response with a value equal to the stored response's current_age; see > Section 4.2.3. The example decrements values in Cache-Control and doesn't use Age. This is not correct. # Nits 14. The [HTTP] and [HTTP-CACHING] references seem to have been inverted :-) 15. Use URI consistently. Aside from base64url encoding, there seems to be a few "URLs" that have crept in.