jiebi/CodeConvo huggingface dataset:
Code change:
representation of the cache's state regarding that origin, for the type of cached response indicated by the "STALE" flag. <del> *VALIDATORS* (0x4): When set, indicates that the "validators" boolean in computing is true. *STALE* (0x8): When set, indicates that all cached responses represented in the digest-value are stale RFC7234 at the point in them that the digest was generated; otherwise, all are fresh. </del> 2.1. A CACHE_DIGEST frame MUST be sent from a client to a server on stream

Related discussion:
text: The reason is that I think the distinction doesn't make much sense, and maintaining it adds a lot of complexity, basically forcing browsers to recreate the digest for every connection at O(N) cost. Under this premise what servers should do is: Push all the resources that are known not to be in the cache digest Push 304 responses for resources that are in the cache digest, but are likely to be stale (short freshness lifetime, etc) Don't push resources that are in the cache digest and have a long term freshness lifetime or are immutable. Does that make sense? I'm not sure I understand your reference to the push cache vs. the HTTP cache in your comment. In light of my explanation, is there still an issue there in your view?
URL is the reference implementation. Happy to change it. Do you have any specific changes in mind?
NAME Thank you for the explanation. I now understand the intent better. I think that we need to consider two issues regarding the approach. First is the fact that a browser cache may contain more stale responses than fresh resources. Below are the numbers of cached objects found in my Firefox's cache (to be honest the date is from 2016, I haven't been using Firefox in recent weeks and therefore cannot provide up-to-date data). total ---: 2,273 1,003 As you can see, large scale websites tend to have more stale objects than fresh objects. In other words, including information of stale-cached objects increases the size of the digest roughly three times in this case. Since performance-sensitive resources (that we need to push) are likely to be stored fresh (since they are the most likely ones marked as immutable, or near-immutable), transmitting only the digest of freshly-cached responses makes sense. Second is a configuration issue on the server side. One strategy that can be employed by an H2 server (under the current draft) is to receive a digest of freshly cached resources only, compare the digest against the list of resources the browser should preload by only using the URL, and push the missing resources to the client. It is possible for a H2 server to perform the comparison without actually fetching the resource (from origin or from cache) since only the URL would be required for calculating the digest.
Code change:
representation of the cache's state regarding that origin, for the type of cached response indicated by the "STALE" flag. <del> *VALIDATORS* (0x4): When set, indicates that the "validators" boolean in computing is true. *STALE* (0x8): When set, indicates that all cached responses represented in the digest-value are stale RFC7234 at the point in them that the digest was generated; otherwise, all are fresh. </del> 2.1. A CACHE_DIGEST frame MUST be sent from a client to a server on stream

Related discussion:
text: The proposal prevents such strategy from being deployed since it requires the ETag values to be always taken into consideration (should they be associated to the HTTP responses). In other words, servers would be required to load response headers of the resources to determine if it needs to be pushed, which could be a huge performance degradation on some deployments. Fortunately, servers could avoid the issue by not including ETags for resources that it may push. I think such change on the server-side configuration would be possible, but we need to make sure if we are to take the path (of removing the fresh vs. stale distinction). Let me explain using an example. Consider the following case: client has with and on server-side, the resource has been updated to When receiving a new request from the client, the server cannot determine if the client has URL in its cache. Therefore, would be pushed. The client, when observing (or equivalent tag), tries to load the resource. Since the fresh resource exists within the browser cache, that would be used. The pushed version is ignored and gets discarded (). This would be repeated every time until the cached object either becomes stale or gets removed from the cache. My understanding is that the browser behavior (explained in ) is true for Firefox and also for Chrome. Am I wrong, or missing something? Thank you for the link. I will try to use it. OTOH, do you have some working code that can actually calculate the cache-digest value taking a list of URLs as an input (something like URL)? I ask this because it would give us a better sense in how the actual size of the digest would be. One way to proceed would be to split the discussion of from Cuckoo filters into a separate issue or a PR. I do not have a strong opinion on the naming or the codepoints. What do you think? NAME
NAME Have you considered the approach using Cuckoo filter to generate GCS? I can understand the fact that you do not want to iterate through the browser cache when sending a cache digest. Per-host Cuckoo hash seems like a good solution to the issue. OTOH, as I described in my previous comment, it seems that sending the hash directly has several issues.
Code change:
representation of the cache's state regarding that origin, for the type of cached response indicated by the "STALE" flag. <del> *VALIDATORS* (0x4): When set, indicates that the "validators" boolean in computing is true. *STALE* (0x8): When set, indicates that all cached responses represented in the digest-value are stale RFC7234 at the point in them that the digest was generated; otherwise, all are fresh. </del> 2.1. A CACHE_DIGEST frame MUST be sent from a client to a server on stream

Related discussion:
text: That is why I am wondering if it would be viable to generate GCS from the per-host Cuckoo filter that would be maintained within the browser. I can see three benefits in the approach, compared to sending the values of Cuckoo filter directly: the size of the digest will be smaller we can keep the distinction between fresh vs. cache. Sending digest of fresh resources only would end up in even smaller digests. Retaining the distinction lowers the bar to deploy cache-digests on the server side. note: you can store the time when the cached object becomes stale in the data associated to the Cuckoo filter entry (assuming that you would have associated data to handle resize, as we discussed in URL). That information can be used when builiding the GCS to determine if a particular object should go into a GCS of fresh resources or that of stale ones less change to the browser push handling (no need to handle pushes of 304 or replace a freshly cached object when an object with the same URL is being pushed) In case of or in the comment above, sending fresh-only digests using GCS would be about 1/3 the size of sending fresh & stale digests using Cuckoo filter. The biggest cost of calculating GCS from Cuckoo hash would be the sort operation. But I think that the cost could be negligible compared to the ECDH operation that we would be doing for every connection, considering the fact that the number of entries that we would need to sort would be small (e.g., up to 1,000 entries of uint32_t), and the fact that sort algorithms faster than O(n log n) radix sort can be deployed (e.g. radix sort). WDYT?
So have a cuckoo filter digest and then put its fingerprints in a GCS? I have not considered that. Need to give it some thought... At the same time, it's not clear to me how that would enable a "stale" vs. "fresh" digests, or handling of improperly cached resources (fresh resources that were replaced on the server).
I would appreciate it if you could consider. To me it seems it's worth giving a thought. Under the approach proposed in this PR, structure that stores the per-host digest would look like below. is required for resizing the filter (e.g., when doubling or halving ).
Code change:
representation of the cache's state regarding that origin, for the type of cached response indicated by the "STALE" flag. <del> *VALIDATORS* (0x4): When set, indicates that the "validators" boolean in computing is true. *STALE* (0x8): When set, indicates that all cached responses represented in the digest-value are stale RFC7234 at the point in them that the digest was generated; otherwise, all are fresh. </del> 2.1. A CACHE_DIGEST frame MUST be sent from a client to a server on stream

Related discussion:
text: What I am suggesting that you could change the structure to the following. In addition to the hash value, each entry will contain the moment when the entry becomes stale. The moment can be calculated when the entry is added. For example, if the entry represents a HTTP response with a , can be calculated as . If the entry represents an immutable HTTP response, then should be set to a very large value (e.g.. assuming that underlying type of is ). When building a GCS digest, you would do the following: step 1. prepare an empty list that would contain hashes of fresh responses step 2. prepare an empty list that would contain hashes of stale responses step 3. foreach entry in cuckoofilter: step 3-1. check if the entry is fresh or not, by checking the value of step 3-2. if the entry is fresh, append of the entry to the list of the hashes of fresh responses step 3-3. otherwise, append of the entry to the list of the hashes of stale responses step 4. sort the list of hashes of the fresh responses, encode as GCS, and send step 5. sort the list of hashes of the stale responses, encode as GCS, and send You can skip the operations related to stale objects (i.e. step 2, 3-3, 5) if the server is unwilling to receive stale digests. Whether the approach can be implemented depends on if a client can determine the moment a response becomes stale. I anticipate that it is possible to determine that when you register the entry to Cuckoo filters (which is when you receive the response from the server).
NAME NAME I'm planning to attend the IETF 100 hackathon this weekend in Singapore. (First timer here. ) I'm happy to collaborate on a (URL) implementation of this spec if either of you are around and interested. I'm fairly familiar with the current spec, having implemented it and .
NAME Wonderful! I'll be attending the hackathon on both days (i.e. Saturday and Sunday). I do not think that I would have time to work on Cache Digests, but would love to discuss with you (or help, if you need) about your work on Cache Digests.
Code change:
representation of the cache's state regarding that origin, for the type of cached response indicated by the "STALE" flag. <del> *VALIDATORS* (0x4): When set, indicates that the "validators" boolean in computing is true. *STALE* (0x8): When set, indicates that all cached responses represented in the digest-value are stale RFC7234 at the point in them that the digest was generated; otherwise, all are fresh. </del> 2.1. A CACHE_DIGEST frame MUST be sent from a client to a server on stream

Related discussion:
text: I've got an incomplete initial reference implementation at URL It doesn't yet include removal and querying (that's what I'll be adding next), but I did run it on a list of ~3250 URL (which I got out of my main profile chrome://cache/) and it seems to be creating reasonable sized digests. One more advantage, the digests seem to be highly compressible when sparse. Results so far: Digest with 1021 entries (so room for ~4K URLs): 5621 in-memory, 5233 gzipped (when filled with 3250 URLs). Digest with 2503 entries (so room for ~10K URLs): 13772 in-memory, 6879 gzipped (same 3250 URLs). Digest with 7919 entries (so room for ~31K URLs): 43560 in-memory, 9984 gzipped (same 3250 URLs). In practice, I think ~1000 entries is most probably enough, but it's good to know we can increase the digest size (to avoid having to recreate it), without significant over-the-wire penalty.
OK, I now have a complete reference implementation and it seems to be working fine. It also exposed an issue with the initial algorithm, forcing table allocation to accommodate a power of 2 number of entries. Latest results for 3250 URLs taken from my cache: One note: the 1021 entries table had 35 collisions, so it seems like it's insufficient for that number of URLs, unless we're willing to absorb extra pushes for ~1% of the resources.
NAME Interesting! It's good to know that we have numbers now. What is the value of P (the false positive ratio) that you used?
P=8 (so 1/256 false positive)
Note that the numbers here may be possible to further optimize. One example is semi-sorting of the buckets which the Cuckoo-Filters paper mentions, and which I have not yet implemented. It adds some runtime complexity, but can reduce the fingerprint size per resource by a full bit, so could have resulted in ~9% smaller digests in this case.
NAME Awesome! Me not being familiar with these data structures (despite reading Wikipedia article ), why does the 1/256 probability (~4/1000) result in 35 collisions?
Code change:
representation of the cache's state regarding that origin, for the type of cached response indicated by the "STALE" flag. <del> *VALIDATORS* (0x4): When set, indicates that the "validators" boolean in computing is true. *STALE* (0x8): When set, indicates that all cached responses represented in the digest-value are stale RFC7234 at the point in them that the digest was generated; otherwise, all are fresh. </del> 2.1. A CACHE_DIGEST frame MUST be sent from a client to a server on stream

Related discussion:
text: The 35 collisions are on top of the false positive rates, and represents resources that we failed to put into the table to begin with (due to both their buckets being full). That rate of collisions seems high compared to the results in the paper, so I need to dig further to see who's wrong...
The collisions are now fixed. It was an algorithm issue, where the entry to be pushed was always the same one at the end of the bucket. I've change that to be a random fingerprint from the bucket, which significantly improved things. The ref implementation is now collision free almost up to the point where the digest is full.
Code change:
For these reasons, data center congestion controls are often distinct from those running elsewhere on the Internet (see controlled- <del> environments.  A proposed congestion control need not coexist well </del> <ins> environments).  A proposed congestion control need not coexist well </ins> with all other algorithms if it is intended for data centers, but the proposal SHOULD indicate which are expected to safely coexist with it.

Related discussion:
text: All I did in that sentence is expand BDP. If you would like to change its content, please file a different PR.
Thanks Sean Turner: Questions: s3.2: This section includes the following: This document applies to proposals for congestion control algorithms that seek Experimental or Standards Track status. So ... if I get an Informational RFC I can do whatever I want? Wondering why Informational isn't listed here. s5.3.2: The 1st para invokes some like requirements language like "ought to" and "it would be helpful". Any reason there isn't BCP 1 4language used in this para? s6: Is "MUST find" another way of saying there must be coommunity consensus? If so maybe: OLD: Unless a proposed congestion control specification explicitly forbids use on the public Internet, the community MUST find that it meets the criteria in these scenarios for the proposed congestion control algorithm to progress. NEW: Unless a proposed congestion control specification explicitly forbids use on the public Internet, the community MUST reach consensus that it meets the criteria in these scenarios for the proposed congestion control algorithm to progress. Nits: s5.1.3, 2nd para: expand BDP. s7.9, lastt para: s/(see Section 4./(see Section 4).
I think this could be read as endorsing the change to BBR - but that isn't the case, maybe: /fixed/addressed/ or something similar, to show the intent.
Code change:
DPoP is an application-level mechanism for sender-constraining OAuth RFC6749 access and refresh tokens I-D.ietf-oauth-dpop.  If DPoP is used to sender constrain tokens, the native client SHOULD use DPoP <del> for every token request to the Authroization Server and interaction </del> <ins> for every token request to the authorization Server and interaction </ins> with the Resource Server. DPoP includes an optional capability to bind the authorization code

Related discussion:
text: Included use cases for OTP, e-mail, SMS confirmation, step-up authentication and registration. Also see and
Code change:
IANA has (TBD) registered the following Claims in the "JSON Web Token Claims" registry IANA.JWT established by RFC7519. <del> : "ash" : The base64url-encoded SHA-256 hash of the ASCII encoding of the "auth_session" value : IETF : Section 9.6.1 of this specification </del>

Related discussion:
text: Removed the need for the new ash claim by inverting the way in which binding works by putting responsibility for maintaining the binding on the authorization server (see issue ).
I do love "ash" as a claim name but (as DPoP co-author and a DE on the JWT Claims registry) I'd strongly suggest that the binding be done the other way around. Basically just say that the AS binds the authsession value to the the public key from the DPoP proof and checks the binding whenever the client sends the authsession. Binding that way is simpler (from the spec perspective anyway) and provides more protections. It's also how most of the binding in DPoP works ("ath" is kind of an outlier and provides somewhat questionable value). URL URL
Suggestion: also require a unique DPoP key per session to avoid risks around session binding.
Completed in
Looks good
Code change:
IANA has (TBD) registered the following Claims in the "JSON Web Token Claims" registry IANA.JWT established by RFC7519. <del> : "ash" : The base64url-encoded SHA-256 hash of the ASCII encoding of the "auth_session" value : IETF : Section 9.6.1 of this specification </del>

Related discussion:
text: Proposed update based on feedback in issue Open question for reviewers (and NAME whether we should allow both or only a single method, and if a single methods should we opt for the least common denominator (dpopjkt) or an authorization challenge endpoint specific one?
Commented over in URL that I think the single method of the DPoP proof header is sufficient and preferred.
I would tend to agree that we should stick with only the header option for DPoP.
I'm good with that. Will create a PR to reflect this.
NAME and NAME I made the changes. please review and feel free to merge if ready.
Because the client interacts directly with the Authorization Challenge Endpoint the authorization code binding can and probably should be done via the DPoP proof rather than the dpop_jkt parameter. This is similar to what but here you could probably get away with just using the DPoP proof.
That makes sense, we should do it the same way that's recommended for PAR.
NAME I was reading the rationale for requiring both the dpopjkt parameter and adding the DPoP header to the PAR request: URL It looks like the goal was to keep client libraries simple so that they don't need to distinguish between PAR or front channel flows. If we remove dpopjkt, do we make it harder for implementors of client libraries? Given that this is a new end-point (Authorization Challenge Endpoint) and a native client, we may not need to keep support for both and we can be more prescriptive, but I wonder if we might cause confusion for implementors as we have established dpopjkt as the least common denominator (the reason for allowing it to be used with PAR end points). Perhaps we should have similar guidance to DPoP on supporting both dpopjkt and allowing the DPoP Header to be added to the Authorization Challenge Response? I guess the question is really if we settle dpop_jkt as a the least common denominator in all DPoP impementations?
I think the in PAR was more about keeping the commonalty of authz request parameters and their treatment on both sides. Not so much about being a least common denominator. I think this Authorization Challenge Endpoint is different enough that just using the DPoP proof is the way to go.
Code change:
IANA has (TBD) registered the following Claims in the "JSON Web Token Claims" registry IANA.JWT established by RFC7519. <del> : "ash" : The base64url-encoded SHA-256 hash of the ASCII encoding of the "auth_session" value : IETF : Section 9.6.1 of this specification </del>

Related discussion:
text: Also, doing DPoP key binding of the needs the DPoP proof - so a client doing DPoP in this context really just should be sending the DPoP proof header.
Closing this as it was resolved in
looks okay to me (pending conflicts that need to be resolved)
Code change:
whether that is to do an MFA flow, or perform an OAuth redirect-based flow. <ins> In order to preserve the security of this specification, the Authorization Server MUST verify the "first-partyness" of the client before continuing with the authentication flow.  Please see first- party-applications for additional considerations. </ins> 5.1. The client makes a request to the authorization challenge endpoint by

Related discussion:
text: Added text to address assigned issues: URL URL URL
tbd: "Due to the inability to securely attest to the first-partyness of a browser based application, it is NOT RECOMMENDED to use this application in a browser-based application."
Thinking out loud, would the hypothetic "SPA attestation" be possible in principle / make sense at all?
Yes, Chrome has a proposal for the "Web Integrity API", but it has received a lot of pushback: URL Safari already shipped Private Access Tokens which are similar: URL
There was some discussion at OSW about enforcing client auth first, before invoking the native flow to further build trust. It may be a good idea to add additional information, perhaps in the security considerations, about ways in which the server can have confidence that the first party app is a "real" first party app.
Yes, I agree. There are couple of ways the server can determine trust in the mobile app. We shouldn't be prescriptive but maybe putting some options in the security considerations would help make it more clear how to do this. Maybe there is best practice guidance that could be put in a doc like for single-page-apps.
NAME to update First-Party Applications section
in Section 9.1 URL
Add new normative requirement for authorization server to verify that the application is a first party application.
One of the participants in the OSW workshop suggested adding a content type parameter to allow them to specify for example a JSON structure or some other data format to control the native app experience. We have been deliberately avoiding defining a new language or re-inventing HTML, but allowing implementors to return complex content types of their own definition may be worth considering if this is a common enough use case.
Make it more clear in 5.2 that this spec expects the response to always be either the authorization code or an error URL Section 5.2.2 needs to make it clear that the authorization server has to define its own error codes URL Section 5.2.2 should explicitly allow more specific JSON content types
Code change:
The algorithm to represent an integer I is as follows: <ins> This integer representation allows for values of indefinite size.  It is also possible for an encoder to send a large number of zero values, which can waste bytes and could be used to overflow integer values.  Excessively large integer encodings - in value or octet length - MUST be treated as a decoding error.  Different limits can be set for each of the different uses of integers, based on implementation constraints. </ins> 4.1.1.1. The value 10 is to be encoded with a 5-bit prefix.

Related discussion:
text: On Sun, Oct 20, 2013 at 05:23:50PM -0700, Roberto Peon wrote: Here's a proposal for that.