It's likely because the field is ignored when parsing fails, but 8941 s 2 allows a field to specify other error handling behaivour.
How so? 8941, Section 4.2 says:
Section 2 has a bit more nuance:
You refer to: ? My reading is that this applies to the preceding text about what happens when parsing does not fail, but additional constraints are not met. If this is not the case, we should consider this to be an inconsistency in requirements and treat it as spec bug. EDIT: opened URL
As pointed out on list, we need to warn people against just using Date as an extension in a field that was defined using 8941.
The warning helps, but it IMHO does not address the larger extensibility problem we have.
NAME can you articulate that (here or in another issue, if it's substantially different / larger)?
I'll try. The main selling point for structured fields IMHO is "a unified parser". You know that a field value is SF-shaped, drop it into the parser, and get a more or less self describing data structure. Great. Now once we add extensions to SF, this get's harder. Starting with the the current proposals: A recipient of a field does not only have to know which top-level field type to parse for, but also whether to switch on support for SF-date or not. Or we would need to say that even when a spec defines a field using 8941, it still's ok to parse it with an sf-date-enabled parser. In that case, it would be up to the recipient to either ignore sf-date-typed extension parameters (if the field definition already allowed future extension), to convert them to an integer, or to reject the parsing result altogether. Retrofit parsing flags: I hope we have consensus that preprocessing values before passing them into the parser will be fragile. So a retrofit-supporting SF parser will either need modes, or the wire syntax for SF could be relaxed so that retrofit would need no new mode. The common concern here is that SF in theory is simple to extend, the process is extremely hard both process-wise and deployment-wise. Ideas: we could simply avoid doing extensions; sf-date is only a "lipstick" flag so that tools can switch on a special display mode - maybe we don't really need it? we could try to define what future extensions mean for specs that are written for the current version of the spec My concern with the current state of things is that a parser implementation will need a set of flags, and each new flag will add complexity not only with respect to the parsing code, but also to API and documentation (how do I get the user to select the right mode, or will she always just select all extensions - and why would that be bad...?), and to test coverage (we need a parametrized test suite, right?).
I think that this is a reasonable outcome. Using sf-date before a recipient is prepared to process it can result in the field being dropped. Now, this isn't entirely satisfactory, because an extension within a field will be dropped by a date-unaware SF parser, but that risk can be documented. Extensions to structured fields defined against RFC 8941 probably don't get to use dates then, at least until sf-date-aware parsers are widely enough deployed that the risk is negligible. Documenting this as a caveat is worthwhile; it's only the current set of structured fields that are affected in this way. I don't think that a flag is necessary for sf-date. (I haven't thought much about your retrofit points just yet, I just wanted to put this there as a potential way forward for sf-date.)
Just to clarify: any of these three? Which means that updated parsers will accept sf-date, and thus not be compliant to 8941 anymore. (I'm personally ok with that, but we really should be clear about that)
Yes, that had been my assumption -- a recipient is always going to need to check whether or not the types it recieves are the ones it expected; e.g., if a field is defined to only allow Strings and it receives an Integer, it needs to deal with that. Same for Dates, in this case. I don't think that non-compliance has any significant impact, as discussed above. Happy to clarify it, but I seriously doubt whether it will have any real-world impact to do so. In the case where a field that specifies (or allows through extension) a Date, the appropriate spec needs to refer to the updated RFC so that an updated parser is used. The extension case is a little less obvious, so we're talking through the text to highlight that now. Regarding retrofit -- I don't think preprocessing is seriously considered by anyone at this point; the question is whether we make it a flag in sf-bis, or 'monkey patch' the spec from afar, just for the purpose of retrofit. So far we seem to be leaning towards the former, but there are risks (as discussed). Note that if we have flags, they're in the parser, but they needn't be exposed to people doing end-user parsing of fields. Or, as discussed elsewhere, we could decide to drop those compatibility fixes. Let's keep discussion of that on issue . I'm not unsympathetic here. I was much more excited about a Date that looked developer-friendly in HTTP/1; now I fear it's not going to be adopted (the HTTPAPI is very lukewarm about it).
Ok, here's an implementation question. In the branch for sf-date, URL currently handles dates as extensions of integers. So somebody expecting an integer would actually see an integer, unless when aware of the new type URL (extending NumberItem). Would you consider that a problematic approach? (I got there just because of code re-use from integers, AFAIR it was not a conscious decision (yet)).
It'd be problematic if the implementation didn't have any way of distinguishing Dates from Integers, because that would be impossible to round-trip -- the serialiser wouldn't know which form to pick.
See linked PR.
Well, if the caller knows about the new types, it will be able to check. The serializer does know about the new types, so round-tripping would happen correctly even if the user of the API wasn't aware of the extension.
Ok, the PR makes things clearer, in that: you can't use sf-date, even inside an extension parameter, unless you update the spec defining the field, and code calling an SF parser will now have to specify which version of SF to use (that's ok with just the three top-level types and one additional flag, but it will get messy if more extensions are being defined)
I would like to avoid the second if possible. That is, you can process with a newer SF version, but you can't produce with a newer SF version. That means that rejection by a receiver isn't guaranteed, but it offers a path toward upgrade at some point (we could decide, collectively, that it is OK to use sf-date in an extension for an older field definition. We might do that based on adoption rates for the new SF version, and memorialize it with an update to the field, but we wouldn't necessarily need to pick a new field name in order to avoid the compatibility risk (we'd just be managing the probability of it happening).
It would be interesting to see more feedback from people defining APIs for SF support...
How does the PR imply that?
Well, if a spec refers to an SF-shaped field based on RFC 8941, parsing it with an 8941bis parser (allowing sf-date) would be incorrect. RFC 8941 requires draconian error handling, after all. When we defined RFC 8941, we consciously specced draconian error handling + no extension points (until the spec is updated), so that's the consequence. I fear that we are in a very fundamental disagreement about how extending the structured field syntax is supposed to happen given the constraints we put into 8941.
Perhaps it would be best to take this to the list. I don't see anyone else who yet shares your point of view, so it would be good to circulate it with a wider audience.
(with two nits)


Replaces
Thanks!
IMHO we need to be clear what the requirements of SF support are. The way the spec currently is written (referencing RFC 8941) means that SF-shaped field values using the new sf-date format are not supported. I don't think this is what we want, so unless we want to wait for sfbis to be ready, we'll need to add some consideration of how compat with SF extensions/revisions is supposed to work.
The intent of the current text is not to limit the use of the flag to only the currently defined formats. New formats are supported if the signer and verifier support the formats. The agreement of what format to use for a particular field is out of scope for this specification, and needs to be agreed upon by the signer and verifier outside of the signature process. This is true for all the current types and will remain true for any additional types defined in the future.
On a high level, this sounds right. As an implementer of a signature library, calling an SF library, what is your expectation what it'll do with sf-date once the spec is published? What if the sender want to sign an integer param in a dictionary, but the field instance contains another param using sf-date?
I would expect a library of that nature to publish its mapping between field names and SF types, and ideally allow that mapping to be edited by the caller of the library. Otherwise, how would a user of the library be able to provide a type mapping for a custom field that the library doesn't know about, let alone a new sf-type?
Understood. Different layers of libs. What I meant is a generic SF library, that just parses/serializes SF fields.
Then you need to know what you're parsing it in to. SF fields aren't entirely discoverable from the syntax alone, you need to know the type explicitly. I ran into this when implementing my own signature libraries. So the signature library needs to have that mapping, and if the underlying SF library doesn't support some new type, then you can't map to it. Once the dependencies are updated, you can provide that feature up the chain. It all seems pretty standard and simple to me, honestly.
How so? I still don't see the path to interop for any update of the structured field syntax, unless this spec at least provides some hints.
You need to know the top-level type (Dictionary, List, or Item) for each field. The consequence of that (AIUI) is that a recipient wishing to validate a signature that uses will need to understand the top-level type of each 'd field in the signature. It'll also need to support the permissable types in those fields -- e.g., if a field allows Date, the recipient needs to be able to handle that. As a result, it won't be possible to reliably verify a signature if your processor doesn't have knowledge of the top-level type, or if it doesn't have support for an extension type in use in one of those fields. However, there is a chance of verifying it still, if the SF-produced form is sent on the wire and not changed at all in transit, and the processor just ignores processing (and in some ways, this is worse than reliably failing). I think this all can be reasoned out by reading the specs appropriately. Documenting it as a tripping hazard would help users avoid interoperability issues, but this specification is already long and dense, and if we also make it a user guide, it will risk becoming unusable. So, speaking personally -- if the above summary is correct, I could see adding a sentence or two to section 2.1.1 at the most; I could also see leaving it to a separate profile/user guide.
[ chair hat on ] This issue is the last thing holding the Signature spec going to IETF LC. NAME NAME please respond to above, particularly: whether such text is necessary whether such text will address the issue when such text, if necesary, would need to be incorporated (before/after LC). Thanks,
I believe it would be good to have such text; and that it should be in the spec, not in a guide that is unlikely to materialize. It should be incorporated before LC (I hope you mean a new WGLC here...?). Given the amount of changes, we really should spend some time reviewing all that changed, and to verify that the open issues have been addressed properly.
NAME can you propose something? I don't see any reason to rerun WGLC, based upon the current PRs; there are some changes (especially in one or two), but they're based on AD review and can be discussed during IETF LC. cc NAME
I would prefer to see your proposal :-). The RFC diff since the last WG version has 143 change blocks: URL We also currently have 17 open issues/PRs: URL IMHO we need to get these closed (can be rejecting or fixing), and also have a look at those that we raised since -13 and closed in the meantime. I don't think we do the community a service by sending this to IETF LC right now.
NAME you are grossly misrepresenting the state of the document. For one, the last WG version, and the one that went to the AD, is -15, not 13, so your diff above is misleading at best. The changes since then have largely not been substantive in nature, and all have been made publicly with the view and input of the WG. The open issues are nearly all addressed by open PRs, which I am waiting for AD feedback before merging (I'm not sure if the AD wants to review the PR text or the merged draft that results). What remains is this issue, as NAME pointed out above. To answer NAME 's question about how to resolve this: I think pointing out as a potential tripping hazard is not necessary but would not be harmful. The precondition to know the type is already in the text as the first sentence about the flag in section 2.1.1: Additionally, the lack of knowledge of the type of the field is already called out explicitly as a required error condition in section 2.5: I would propose we simply add a note to 2.1.1 of the form:
Well, it's hard to say what remains to be done until an issue is actually closed. We're all volunteers here, so it's good to make things as easy as possible to reviewers. So, trying to rephrase: let's get all open issues closed (one way or the other), and let the people who raised the issues give an opportunity to provide feedback before sending this back to the IESG. (I, for once, am not convinced that I agree with the proposed solutions, but due to the type of diffs (long lines) it's a bit tricky to understand what actually changed) works for the sending side; but what is a recipient supposed to do when the sf flag is present and the field value does not parse due to sender and receiver disagreeing about the SF version? Also, that only affects the toplevel type of the structured field. It does not address the case where an extension parameter is added is an sf-date (or any future new type).
NAME until you propose text, it will be hard to say what kind of text you think would close this issue.
Except for this issue and two others recently raised by you (which will be considered as IETF LC issues), all of the issues and PRs you mention were generated by the AD review before IETF LC; this is a normal part of the process that does not require going back to WGLC unless the AD asks for WG review, which . NAME made a reasonable proposal. If you disagree with it, make your own.
If the proposal was: Then this isn't sufficient as it only applies to the toplevel type (see URL). NAME - I believe you are in the best position to make a proposal; but that said; I can try something later today.
So, we have in 2.1.1: This implies that the "sf" parameter can only be used on fields that conform to RFC 8941, no extensions allowed. I would suggest clarifying that, at the end of 2.1.1, with: "Note that the normative requirement to use the SF serialization algorithm precludes any use of future extensions of the structured field syntax. Support for future versions of SF will require an update to this specification." I believe this matches what NAME suggested.
Except that your proposed text is incorrect. The implication you are drawing is not true, nor what others have taken from that text. The use of the parameter does not preclude extensions to RFC 8941, as has been discussed at length here and on the mailing list. Extensions to sf types would not require changes to the signatures spec. I propose closing this issue without change to the signatures spec.
Sorry. Mark asked me to propose text, and that's what I did. The text has a normative requirement to use an RFC8941 serializer, so the proposed text is correct. That we disagree here is proof that a clarification is needed. If you feel that that p.o.v. is too restrictive, we'll have to somehow relax the requirement on the serializer (for instance, by stating that the serializer needs to implement 8941 or a successor RFC - that is an RFC that obsoletes 8941). FWIW, I agree that this would be good. But it is not what the spec says.
No, we reference the current document and if that document is updated or obsoleted by something else after publication then you as an implementer go and follow that. That's how updating RFC's already work. All the specs and systems that implemented RFC2616 didn't suddenly break and become invalid when 7230 or later 9110 came out. Here, It's up to the updaters of 8941 to make sure there's A serialization section. Your view of specification dependency is not at all in line with reality.
I see where you're coming from; I'd appreciate if you would do the effort to understand where I'm coming from. The difference here is that any spec that extends 8941 with new types by definition is not backwards compatible. This is because 8941 has no extension points, has drastic error handling and thus requires a wholesale spec update for new things. This is very different from most other RFCs that we're using here. If there is agreement about what we want, why don't we just say it?
To illustrate further: RFC8941-vs-8941bis is like XML1.0-vs-1.1 or HTTP1.1-vs-2.0, not like RFC2616-vs-RFC9112.
That's a very specific definition of 'not backwards compatible' and one that I suspect many would be surprised by. Just because there are no explicitly nominated extension points doesn't mean you can't evolve the specification in a backwards-compatible fashion; the key requirement is that valid inputs per the 'old' version are also valid inputs per the 'new' revision. That is the case for sf-bis. It is true that an invalid input for RFC 8941 will now become valid; specifically, a type value beginning with 'NAME used to generate an error, and now will not (provided that the following characters are appropriate). The reasonable question to ask at this point is whether it's realistic / probable that an application will be depending upon that error being thrown to operate. Can you suggest when that might be the case? Because I find it doubtful in the extreme that this will cause real-world problems.
I agree that this wouldn't cause real-world problems. I just also wish that our specs actually say what we think should happen, instead of requiring people to figure out. So in this case, I think we can solve this by saying "RFC 8941 or a revision obsoleting it".
Since NAME acknowledges that this doesnt affect interoperability and this is merely a "wish", NAME why don't you go ahead and incorporate your proposal so we can ship this spec?
NAME - please don't claim what I said something I did not say. My position remains: the spec should be clear about what it expects implementers to do. Right now it is not. If the agreement is "use RFC 8941 or a future revision", why don't we say that?
Proposed change: URL


... or it's a clarification that aligns the text in the two different sections. Sounds like we should discuss on list.
I still dont understand why we have some of the "strict" stuff in 1.1 and some in 4.2. I would move the paragraph from 4.2 to 1.1 to improve the chance people actually read it.
Disagree; implementers are more likely to look at the parsing section, not what they perceive as boilerplate at the top. 1.1 covers the philosophy and general approach; 4.2 talks about the implementation details.
"This is intentionally strict […]" sounded philosophical to me, but whatever :-)
URL It appears that some read the last sentence: as saying that the generic draconian handling of parsing errors can be relaxed.
It's saying that a generic parser will fail, but the field-specific handling of that failure might do somthing else, including try to parse the field using an alternative method. SF cannot constrain what a field does with the output of parsing.
That sounds like "we require draconian error handling, but if there's an error, you are free to do something else". Of course we can't force anybody not to do that, but we should be clear that this is not what the spec says.


AD review feedback (thread at URL) and some minor editorial updates
thanks Mike, nits have been addressed
Looks good; two nits.


Closes URL
I suspect a title like "HTTP Resumable Uploads" or "Resumable Uploads for HTTP" would be more clear -- not referring to HTTP will pull in readers looking for other things, and calling it a protocol reinforces that it's separate, when we're trying to make it an extension to an existing protocol.
Good idea to include HTTP in the title! I updated the PR.
Great suggestions, Lucas! Thank you very much!
LGTM, thanks for picking it the pen.
The title of the resumable uploads draft starts with "tus", which is a little weird as the inclusion is entirely unexplained. If the intent is to acknowledge something, might I suggest the Acknowledg[e]ments section.
Agreed. I think this helped during the "pitch period" as a differentiator for this proposal vs others. However, now its an adopted document the lone use of the term is odd. I'll prepare a PR that gives a nod back to the tus v1 spec that inspired this.
+1
I opened a PR for this: URL NAME Let me know if you had something different in mind.


some content-coding are "not deterministic" ;) not only encryption-related ones.
NAME great! I applied them :) Feel free to merge!
merged, thanks
James Manger wrote:
yeah I think RFC 8188 was the target of the section here. NAME can you recall? What can we add to make this section a bit more clear?
That's correct. And the suggestion wrt different compression levels is correct to! This is worth mentioning and maybe highlight that it applies to a specific kind of content codings.


Murray suggested some things that we could change about the way new IANA registry was being handled. This change: tries to make it clearer that this document uses a new registry that we will need IANA to create moves rote IANA instructions to the IANA considerations better highlights interesting hash algorithm considerations for implmenters clarifies the registration procedure and expands on the expectations for the Designated Expert(s)


Add reference for obs-fold, add note about transforms,
The spec several times refers to the term obs-fold, but doesn't say where it's defined (-> URL). Furthermore, in 1.3 it claims that addition of obs-fold could be permitted under certain circumstances. That IMHO is incorrect.
Adding the reference makes sense. The signatures spec doesn't change how the messages are created, nor does it make more allowed than it is now, it just tells people what to do with the messages that they have even if they have in them.
: This is misleading. No HTTP permits addition of leading/trailing whitespace. Leading/trailing whitespace in field values by definition is invalid.
While technically true, many (including implementers) won't understand the nuance Here. Given the impact, it's better to be over-inclusive, I think.
If invalid changes are included, then it might be best to either say that some of these changes might be invalid or point specifically to those that are.
Yes, my proposal would be to split the list into two; the second just listing the transformatios that might happen in reality despite bing forbidden.
NAME I agree that we need to prepare developers for the messy reality of HTTP in addition to what's strictly allowed. What else would appear in this second list?
The only other thing that I can see right now is addition of obs-fold.
Speaking of which: there are other transformations like parsing and re-serializing field values, which are certainly allowed. Shouldn't these be mentioned here as well?
NAME Re-serialization of a field value by an intermediary would likely break things in an expected way. It was my impression that this was not allowed by intermediaries in general. A structured field does help this, and the flag protects against that kind of transformation, as mentioned in the section.
I don't think we have a rule anywhere that would keep an intermediary from parsing and re-serializing fields. And even if that was the case, the same would be true for the original point (addition of leading/trailing WS), so I'm trying to understand where we draw the line.


Since next-hop-aliases is a String parameter, the syntax allows an empty string . In cases where there is no chain, is it advisable to send the empty string to indicate this, rather than omitting the parameter? If so, it might help to add a sentence somewhere that highlights this usage type.
That's a good question! I don't think there needs to be a normative requirement here, but I think it's reasonable to have signify that there were no aliases.
This mention is clear. LGTM


A signature over another signature does not provide the transitive protection that it seems it should. The examples and advice have been updated to accomodate this.
NAME NAME can you please verify the signatures on the updated examples in this PR?


[ ] to obsolete the IANA Digest Algorithms Registry or define another registry [ ] it can stay as historical ~identify whether and how it should stay~ [x] if it should stay, the note below should be fixed.
I think it's easiest to just add a request to update the note in the IANA considerations of digest spec. E.g. current: something like
cc: NAME guidance welcome
Note: this has been fixed. the IANA Digest Algorithm Registry Note not to mention "message body" since it's not even mentioned in RFC3230.
NAME NAME what is expected to happen to URL after Digest's deprecation? Can it be marked as "historical" to avoid issues with current Digest implementers?
Yes, IANA can be instructed to do that in IANA Considerations.


Add requirement for unprompted auth to use TLS 1.2 with extended master secret or later. Fixes httpwg/http-extensions
Please mark this PR as fixing the corresponding issue
From Ilari Liusvaara on the :


Fixes httpwg/http-extensions.
Please mark this PR as fixing the corresponding issue
From NAME on the :
The conservative thing to do here would be to insist that the key be unique to the protocol. We have domain separation in our outputs, so we don't need to worry about unprompted auth messages being used in cross-protocol attacks, but a different protocol (that doesn't use context strings) could possibly be induced to generate unprompted auth messages. We also need to worry about key compromise. Imagine a protocol that leaks the private / secret key, that shares a key with unprompted auth. This doesn't even need to be a bug, it could be a commit-before-reveal style protocol. (Obviously that's a pathological example, but it shows we can't assume composability with all protocols) If we want to do a formal analysis (which I do) I think we need to be conservative here.
SGTM


The user ID parameter "u" effectively identifies the keying material that servers might use to verify the authenticator sent in the header. As noted on the list, this is more or less a key ID, and I think leaning into that framing could be helpful. For example, beyond avoiding the confusion raised on the list, it might also be more ergonomic for different types of authenticators. One could imagine using a for unprompted authentication where the server only learns that someone with a valid private key produced the authenticator but not necessarily which one.


OK with me.
doesn't return . Without that, the number itself isn't necessarily enough to determine what the type is (necessary for parsing Date).
So what we need to prevent here is that: parses as date.
I don't think this is necessary; the result of Parsing a... already has a type, and that's already checked in Date parsing. Nevertheless, see PR...
The PR isn't correct; it fails to account for the different return signature everywhere it's called. Fixing that is much more invasive, so I'm going to push back on this more strongly; it isn't necessary. What Parsing an Integer or Decimal returns is typed; it's either an integer or a decimal. This can be seen in other places as well -- e.g., in Serializing a Bare Item ("If input_item is an Integer, return..."). No change is necessary here.
NAME NAME can I close this with no action, or should we take it to the list, or...?
So your assertion is that a value inherently carries a type? That's not obvious to me.
Yes. defines those types; the serialisation algorithms take them as parameters, and the parsing algorithms return them. That's reflected in the introduction text for each individual algorithm.


Based on
Right now the document contains the (user ID) parameter. Thinking about it some more, this is more about describing the key than the user, see httpwg/http-extensions. In addition to that change, we should add text warning about the tracking risks or this and how to avoid these issues.
It seems to me that there's room for both user-ID type uses for the "u" (in the employee remote access model, e.g.) as well as the more indirect key-indicator type uses (in the Internet Freedom model of distributed communities). I'm especially interested in the latter - use cases where users can prove they are in possession of a valid secret without requiring a hard user identifier (one that attaches them to a permanent/billable/irrevocable external identifier). The draft does not currently provide an Authentication Scheme that directly offers this latter capability, however (though it's possible to overload on the "u"/"k" parameter if the server and client agree on the scheme for doing that). I'm unable to steelman the case for "u" (or "k") being a "super-cookie". The imagined use cases in my head have this scheme tied to a single service provider and employed on the first hop. I don't understand the language being used in the list commentary on this topic (e.g., "Each site (*) could get a different key pair and key identifier."). My assumption has been sites issue credentials as they see fit without reference to any other site. The commentary implies to me that there is some overriding entity distributing credentials to many sites (a la Privacy Pass). I did not think Unprompted Authentication addresses that space. Further, if indeed we need to address that space, it seems to me the "super-cookie" burden of proof is then with THAT scheme, not Unprompted Authentication. The "document it" point might be the salient one: "This is probably another case where documenting a little more detail about the usage context could help.". Here's a start: Sites offering Unprompted Authentication are able to link requests from individuals clients via the Authentication Schemes provided. However, requests as not linkable across other sites if the credentials used are private to individual sites.


Based on
The draft could benefit from some example use cases up front in the introduction.
Concise Use Case Description: Unprompted authentication, as defined here, serves use cases in which the provider of a service or capability wants only "those who know" to access it while all others are given no indication the service or capability exists. The conceptual model is that of a "speakeasy". For example, a company might offer remote employee access directly via its website, or access to limited special capabilities for specific employees. Members of less well-defined communities might acquire metered access to geography- or capability-specific resources by an entity whose user base is larger than the available resources can support. Unprompted authentication is also useful for cases where a service provider wants to distribute provisioning information to its resources without exposing the provisioning location to non-users. Edits/Additions welcome
Version 2: Unprompted authentication, as defined here, serves use cases in which the provider of a service or capability wants only "those who know" to access the service or capability while all others are given no indication the service or capability exists. "Knowing" is via an externally-defined mechanism by which user identifiers (required here) are distributed. The conceptual model is that of a "speakeasy". For example, a company might offer remote employee access to company services directly via its website, or offer access to limited special capabilities for specific employees, while making discovering (probing for) such capabilities difficult. Members of less well-defined communities might acquire access to geography- or capability-specific resources by an entity whose user base is larger than the available resources can support (via that entity metering the availability of user identifiers temporally or geographically). Unprompted authentication is also useful for cases where a service provider wants to distribute user-provisioning information for its resources without exposing the provisioning location to non-users.
Version 3: Unprompted authentication, as defined here, serves use cases in which a site wants to offer a service or capability only to "those who know" while all others are given no indication the service or capability exists. The conceptual model is that of a "speakeasy". "Knowing" is via an externally-defined mechanism by which user identifiers are distributed. For example, a company might offer remote employee access to company services directly via its website using their employee ID, or offer access to limited special capabilities for specific employees, while making discovering (probing for) such capabilities difficult. Members of less well-defined communities might more ephemeral identifiers to acquire access to geography- or capability-specific resources, as issued by an entity whose user base is larger than the available resources can support (by that entity metering the availability of user identifiers temporally or geographically). Unprompted authentication is also useful for cases where a service provider wants to distribute user-provisioning information for its resources without exposing the provisioning location to non-users.
"security by obscurity", yes?


Ilari suggests on the :
to this. It's been implemented for exported authenticators and isn't too challenging.


s/ise-case/use case e.g. -> e.g., nit pass


I think the alias draft should probably have a (non-normative) reference to , in particular noting that: can be populated from the output of . can be used to emulate or substitute for .
I think the flag to only gives you the "canonical name" which is the final CNAME target at the end of the CNAME chain. If you want the full set of interior names across a chain of multiple CNAME records I don't believe you can retrieve that with .
Yeah, I'm hesitant to add references to system APIs like , and particularly for the reason given above. NAME what do you think?
I think AI_CANONNAME is important historical context here. You can't understand where the draft is coming from without it. I also think that this extension will often be implemented by wrapping getaddrinfo, and some guidance about whether that is compliant would be appropriate. I think Robert's comment raises a good example of why this is not trivial, and hence is worth mentioning.
I'm not sure is really required to understand the context of the draft. We don't use it at all on iOS/macOS implementations for current CNAME cloaking detection. I do see that it may be good to warn that it is not sufficient to just wrap up .
Thanks LGTM


Follow up to the IANA review of the digest spec. We asked them to deprectae the old registry, so lets add a note to it to clarify what the new expectations of that registry are.


Reframe use cases that had previously signed signature values to avoid problems with this approach.
This looks good to me! Summary of the changes: Explicitly flagging that the application / implementer must specify how request-response binding is to be achieved (if desired). Removed all references to request-response binding in the main body. Removed all signatures of signatures from the examples Added guidance that applications SHOULD sign all signed components of a request when generating a signed response. Added guidance that generating signatures of signatures is NOT RECOMMENDED when generating responses. Added guidance that generating signatures of signatures is NOT RECOMMENDED when acting as a proxy between a request / response.


Addresses encodings of signature component values for query parameters and field values.
: This seems to be inconsistent with Section 2.2.8 ("Query Parameters"), which could create non-ASCII component values.
FWIW, a query parameter (after application of URL) could contain CR, LF and other control characters.
So we likely need to serialize information extracted from query parameters using some kind of encoding; maybe an SF Byte Sequence.
This is tricky -- originally the query parameters were kept in percent-encoded form but from WG discussion we changed that to just use the unencoded value instead since several percent-encoded forms could be used. However it does look like the unencoded form could end up with problematic values here, so maybe we need to go back to that. I'd rather us use an encoding native to the value rather than inventing something to put on top of it, even trying to re-use the flag we've already got defined for headers.
And we did that because to extract query parameter values, we need a query parser, and that is defined the way it is. I believe that decision was good, we now just need to figure out out to transform the extracted values so that they can be used in the signature base. (And, FWIW, at the end we also should have an example for a case like that in the spec).
In 2.2.8, it might be good to mention that the referenced algorithm only supports query parameters using (percent-escaped) UTF-8 encoding (this came as a surprise to me because I assumed it works the same as the algorithm used for forms decoding).
in 2.1.3: What if the field value contains non-ASCII characters (from obs-text)? Of course that could be considered an error, but I believe the intention is to be able to represent anything here. So the text should refer to the field value as byte sequence, in which case the encoding step would not be needed.
This text was added in response to a comment about needing to know which encoding to put into the byte sequence input, and the commenter suggested ASCII as the base for it. If field values have a well-defined byte sequence that isn't ASCII characters only, then we should refer to whatever that is from the HTTP docs.
Well, field values in HTTP can be anything. It's obsolete, it's deprecated, but that's what it is. So we need to deal with it one way or another. I could live with UTF-8, and a note that if the octet sequence does not decode as UTF-8, you can't sign it.
NAME - yes, you can merge and close issues as you wish, you are the editor. But by all means do not submit a new draft until the changes have been reviewed by those who opened the issue. (cc chairs NAME NAME )
As far as I can tell, the changes require percent-encoding only for non-ASCII values. That is, the character U+0080 would get the same encoding as a verbatim "%80" in a field value. I believe this is a problem.
This issue has been addressed. There is no percent encoding needed in this section since the value is taken directly from the bytes of the field in a binary-wrapped representation, and the bytes are encoded using the base64 serialization of a Byte Sequence from Structured Fields:
I'm talking about the simple case, not the one where Byte Sequence encoding is used (yes, the issue title doesn't match anymore).
Ok, opened new issue URL


Import obs-fold, reference US-ASCII, enforce ASCII-ness of Signature Base


There are currently some uses of "serialise" in place of the far more common "serialize", including one case that breaks the pattern of header names ("Serializing a List", "Serializing a Dictionary", "Serializing an Item", …, "Serialising a Date"). This PR also includes an analogous update of "summarises" to "summarizes" to increase the general pattern of American spellings.
Speaking Danglish myself, I am disqualified from having an opinion on this subject matter :-)
Despite my Australianised sensibilities, I see that 8941 was normalised to American spelling by the RFC Editor, and changing things now would introduce more diffs. Thanks for the PR.


This moves the values that were in the Encryption header field to the start of the payload. This provides a meagre efficiency gain as well as removing the need to have two correlated header fields. This should go most of the way to address WGLC comments.
Looks good to me in general. That said; this removes the parsing weirdness for "Encryption" (good), but not for "Crypto-Key", right?
NAME happy to correct any parsing weirdness, but need to know precisely what it is first.


Sorry for noticing this so late. I don't think the security considerations of in retrofit work out. (Also CC NAME who is much better at web security than me.) If we introduce two ways to spell some field, we need to worry about whether this can allow various issues when sender and receiver don't agree on what's going on. The draft mostly leaves this to the future, but it does include some about this: This seems to put the onus on the sender, not the receiver. If you don't know the receiver accepts the alternate representation, you can't send it. It includes no corresponding receiver obligation, I guess on the assumption that if you see SF-Cookie, you can assume the sender meant it? I don't think that works. In a browser, the sender is a combination of browser logic (which has the final say) and JS (with a complex trust relationship). The browser logic specifies some which JS cannot set. Other HTTP systems have similar splits: an HTTP serving frontend may get fields from a CGI script or act as an intermediary, but it cannot allow the downstream code to specify fields like . These rules typically look like a blocklist with the default behavior to pass fields through. All this is to say, browsers won't let JS set the field directly, but setting is perfectly fine, up to CORS rules. A receiver may see that text and incorrectly assume that processing is fine, breaking some cookie invariants. Or vs , which will break some sites' CSRF processing. Beyond just blocklists, a retrofit-unaware HTTP cache that processes caching fields but passes through other fields will likely make a mess of the mapped caching fields. If we prefixed the names with , that would at least meet the browsers' rules, though I worry it'll still break other intermediaries. It's also a little unsatisfying of a fix. We could say that a receiver cannot process these either unless it's received some explicit negotiation that the sender knows about this. That's vague and unspecified, but probably would work, depending on what the intent is here. This is a bit handwaivy because I'm not sure what the use cases are here. But if we require explicit sender and receiver negotiation, it's unclear what we're getting out the parallel field names in the first place. It seems to me that's where all this risk comes from. Giving alternate names interferes with pass-through logic across the pipeline. Maybe we can get a more robust story, inspired a bit by (I'm just assuming this is one of the main use cases here) is to say: The text representation of is what it is. If this part of the system uses the text form, use the existing syntax The structured field representation of is this mapped thing. If this part of the system uses structured fields, use that syntax At boundaries where forms change, convert. We need to be a bit careful about fallibility here, but perhaps: Conversion from text to other forms is allowed to fail, since you can just fallback to the text form. Conversion from other forms to text probably needs to be stricter? The difference between mapped and normal fields is the structured field and text representations don't directly align, so they need to be treated a bit special Like I said, this is handwaivy and definitely incomplete. But it feels to me like something in this might be more sound. It makes it more obvious we have to be sure what representation we're using at each layer and there's no risk of one side thinking something is a generic header and another thinking it's an alternative representation of a special header.
This seems like a plausible risk to me. I'm not as familiar with non-browser use cases, but I can certainly imagine confusion that would result from clients being able to create mismatches between and . I can imagine ways to deal with this in browsers (in addition to NAME suggestions, we could add as a , just as we've done for and ). It's unclear how helpful that would be for non-browser usecases.
Main nuisance with prefix is that, on the receiver side, you don't know a priori if the client is an updated browser, which knows about the prefix, or a preexisting browser which does not. I suppose you could do UA sniffing, but let's not design a system that requires UA sniffing to work if we can help it! :-)
That's fair. would be safe without a change to Fetch. Still, given my expectations about the current deployment of mapped fields, I think we could reasonably get ahead of them in the browser world. Not at all sure about the rest of the ecosystem...
I like the direction that if you've already negotiated support, you could just replace the legacy headers with their spiffy (SFfy?) new equivalents using the same names, and if you haven't negotiated support then you have no business sending these variants and expecting them to work. Of course, that means this draft probably can't get away with "We don't define a way to negotiate this, but you do that."
I think we'd avoid needing "OUGHT TO" in that model. That model is more explicit that these are two incompatible representations of these fields. The negotiation requirements become more straightforward, I think: E.g. draft-nottingham-binary-structured-headers meets this requirement because you set a flag on the message, and gates usage on a setting. A hypothetical SF-based HTTP API would also meet this requirement because it's unambiguous that takes some in-memory structured field representation.
Hey David, Yes, I've been somewhat concerned about the potential issues in this area for a while. Minting new field names for the alternative forms was the initial approach, but I was half expecting someone to raise this issue :) One thing: No; the assumption is that a recipient sees SF-Cookie, they'll ignore it unless they've positively opted into it meaning something. Perhaps, as you point out, that should be more explicit -- e.g., say that these fields MUST NOT be processed unless the sender does [magic]. Making sure that evidence of [magic] is propagated properly may be tricky, though. I could also see removing the new field names. That should work for many contexts, although I suspect it might make handling the new forms difficult in some. Prefixing with doesn't seem very attractive to me.
Ah interesting. So I guess the middle option, "require explicit negotiation on the receiver" was actually the intended interpretation. That's not how I read the draft. It says "implementations are prohibited from generating such fields unless they have negotiated support for them with their peer" without saying anything about the recipient's responsibilities. So it sounds like, at minimum, we should update the draft. Getting that right in the presence of a chain of intermediaries is quite subtle however. Suppose we go A -> B -> C and both B and C support mapped fields, but A does not. B must be careful not to forward along a mapped field from A. E.g. it might decline to advertise mapped field support to C because A doesn't support it. Or it might reject all mapped field names from A, on grounds that it must have been invalid. Moreover, "intermedaries" has to be intepreted very loosely. Every processing step in the entire HTTP pipeline needs to carefully manage these alternate names. This seems a disaster waiting to happen. I think I'm now convinced this is the only plausible option. Regarding "many contexts" and "some", do you have use cases in mind here? I saw draft-nottingham-binary-structured-headers, but I gather there are others? Something to keep in mind is that this draft intentionally punts figuring out the negotiation design to the future anyway. That means this is also the more flexible option. If we define , etc., now, we have permanently committed ourselves to this security problem. If we decline to define now, we can still choose. We can always define the parallel field names later, should something that needs them come up. (Of course, I'd raise the security problem again, but it'll be easier to reason about with a concrete use case! )
I guess this raises another question: how do we handle mapped field values that cannot be represented in the underlying text representation? Given how many intermediaries and intermediary-like constructs are involved in HTTP pipelines, and given how every HTTP system today uses the current syntax, I suspect mapped values that cannot be represented in the original syntax have to be treated as an error. Which means I think we need to go through the exercise of writing SF-to-text converters for each mapped field and then narrowing the allowed inputs until that converter is infallible.
It sounds like removing the field names is the best path forward. Yes, for those, the application using retrofit needs a fallback, just as it does for compatible fields. If that isn't obvious from the document, it should be clarified -- perhaps in a new 'Using Retrofit Fields' section.
I could very well be incorrect, but it sounds we want to have alternatives per each hop. Does that mean that these mappings would be best represented by ther per-hop pseudo headers that we have in H2 and H3? Not that I feel that doing so would be the best option, though.
Ooh yeah, per-hop is a good way to think about this! For pseudoheader vs. something else, I suspect it'll depend on use? draft-nottingham-binary-structured-headers already has a flag, so it probably could just use the original names, though pseudoheader names would work too I suppose. The existing names has the minor benefit of being able to reuse the existing HPACK static table. Some sort of SF-based HTTP API like probably (?) doesn't want pseudoheaders in the API and can just use the original names. But I haven't put much thought into that. If one wanted to send them in their textual form in existing frames, we probably need pseudoheaders. Though I don't know if we really get much value out of defining that, over just using the existing syntax. shrug We can also punt this problem to documents that want to use this, if we're not sure yet. :-)
If you want to use an invalid field name, there are a lot more options than putting a ":" in the first byte. You need to negotiate that usage, but then you can do anything at all, including using that to signal lots of stuff. (If you want to avoid the extra byte, you can pack data into the high bit of each byte...)
I feel like punting is the right solution, unless we can come up with a convention that addresses the identified issues in all cases.
Not acting is a decision of a sort. But I'm not sure what that would concretely mean for retrofit? No prefix? Or just that we shouldn't worry yet about the effect this has on smuggling through WAFs and whatnot?
I think it means: No new header names; applications that use mapped fields need to define their own way to distinguish them A new section about these considerations


message signatures are just one part of an overall system, and this adds language to make that expectation more explicit in the introductory sections.


Point out that many frameworks smush together form parameters and query parameters into one bucket, and that can cause unexpected shadowing. Some examples changed to avoid ambiguity.
This is great.


Proposed fix in URL - note that this is an incompatible change.
FWFW, if the argument is that not escaping the escape character is actually ok for this purpose...: in that case the prose should actually explain this.
I actually do think it's ok to not escape the escape character. If you've got non-ASCII header values you're already kinda out in the weeds in terms of processing the header bytes. Ultimately the signature base really only needs to have bytes, but its input is constrained to ASCII because (1) all derived components are already constrained this way (2) component names and arguments are already constrained and (3) header component values (here) are SUPPOSED to be constrained to ASCII, but might not be in some weird corners as you've pointed out. All that the newly-introduced percent encoding is doing is putting bumpers around the weird corner that isn't supposed to happen but might in some cases. I'd honestly be happier with putting advice to use the binary sequence wrapping ( flag) on problematic non-ASCII header values instead of doing percent-encoding and requiring universal escape of the escape character when the encoding isn't going to hit the VAST majority of use cases. That would reverse the previously-applied fix but I'm fine that.
That works for me. If we combine that with the "MUST produce an error for non-ASCII" in the signature base generation (and people actually do that check), we should be safe.
OK, I'll work on that, unless you want to take a swing at it.. Since we've already got the cut-out for fields that don't behave nicely as lists (specifically Set-Cookie), we've got a good space to put this advice. I think an error on generation makes perfect sense here too. I'll back out the percent-encoding for non-ASCII headers at the same time (but note it'll stay for query parameters, where I do think it makes sense to use).


Encodes query parameter names to match values, to avoid non-ascii or otherwise problematic values.
In 2.2.8: What if the query parameter contains non-ASCII characters? I think this needs to say that the name parameter needs to contain the raw (percent-encoded) name.
Good catch, I believe you're correct.


LGTM
On the list, Rob Sayre asked: I agree it seems we can improve the text here a little. Maybe NAME or NAME can elaborate as to why a digest trailer is not suitable in this case?
The reason is that in order to produce a MICE hash, you need to process the content in reverse order. Therefore, there is no reason not to put the hash in the header. The advantage you get in return is that you can process the response in natural order.
Thanks martin. We should just say it that way, because it is clearer to the reader. I'll follow up with a PR.


The "" set includes ".", but we actually need to escape "." to avoid attacks.
Hm, my impression is that this attack is about making a period within a label look like a label separator. By the time that you have a string for a name, it would already need this kind of escaping done. Put another way, the "." characters we have in the string are indeed label separators already.
The draft doesn't specify how to construct the DNS name string (and in general there is not a great specification for this). The most common convention (noted in RFC 1035 Section 5.1) is to precede "." inside a label with a backslash. This draft would then percent-escape the backslash, but not the ".", so there would indeed be a "." character that is not a label separator in the final header field value. Whatever escaping convention you choose, this is sufficiently non-obvious that I think a very clear specification and some examples are probably in order. (This whole rigmarole is normally not a problem because URIs are restricted to contain only "hostnames", which cannot have weird characters in the labels.)
NAME can you look at URL
I realize that this is now resolved, but isn't it also possible that we could say "this field cannot be used to express names that include a literal period (".") in labels" ?
NAME yeah that’s an option, although it could theoretically incentivize using dots in labels as a way to hide the CNAME from being reported
Sure. But you can add another attribute called "this-site-is-abusing-this-mechanism" for use when that happens.


NAME please take a look!
Without going through a proxy, clients implement CNAME cloaking mitigations on the basis of DNS information they see during resolution, which is totally reasonable. If resolution is subverted (or whatever) and the CNAME information is modified, these client checks might not work. When going through a proxy, the proxy is the one doing DNS resolution, so it seems like any sort of funny business that one might do to DNS answers for the proxy might affect the client's ability to implement cloaking mitigations correctly. The security considerations might benefit from a bit of expansion to cover this additional aspect of the threat model.


We've been circling an answer to this for a while. The entire gamut of possible solutions is broad, and we haven't had much luck in reaching clarity here. One the one end of the scale, it should be perfectly OK to send a request for an origin over an authenticated TLS connection. But we still have the (entirely legitimate) concern there is that some servers might get themselves confused by this. The other end of the scale is the bells and whistles JSON stuff. NAME seemed OK with this based on his implementation experience, but it is a little complicated. We found too many corner cases for me to be happy that it implementations wouldn't end up busted. And now that we insist on authentication for the server, many of the features didn't make sense. We've also considered an HTTP/2 setting. That's appealing, but it does limit the applicability a little. This change aims more to the conservative end of that scale. It keeps the resource, but simplifies it, reducing it to a flat list of origins. The client only needs to acquire this from the authenticated server. This doesn't defend against Alt-Svc attacks mounted by attackers with the ability to both send header fields and run an authenticated server, but we're in a very strange place if this is the sort of capabilities we ascribe to our attackers in our threat models. I've explicitly added here. I believe that's reflective of consensus, but that part is easy to revert. The text about client certificates is now clearer.


This PR tracks changes under discussion with the RFC editor. (Note that I haven't renamed the file to the RFC number, because that hasn't been done in other drafts in this repo.) When AUTH48 completes, I will add the commit moving this draft to the archive and merge it.


think its a case of s/an/and
The abstract says is it really , is it some other phrasing a little more technically correct?
LGTM thanks


ballot position feedback
[x] §6.1 Recommend adding cautionary language about the capabilities of an adversary like those stated in Peter’s SECDIR review [x] Appendix A, typo[x] Section 6.5, e.g.


SGTM. Feel free to merge if you are sure we won't need this. Kind regards, R
John Scudder raised during IESG review: algorithms that use a reserved token value that cannot be expressed in Structured Fields". This is a well-formed sentence but I have no idea what it means. I made a desultory attempt to suss it out by searching the document for "token" and this was the only occurrence. If people who will actually be making use of the registry can be expected to make sense of it, then feel free to disregard my comment, of course. This reminded me at some point, I'd sketched out a design for the "Hash Algorithms for HTTP Digest Fields" registry that worked differently with what we ended up with now. In that design, it would have been possible to register an algorithm in the table under some friendly name and then separately register some Structured-Fields identifier that it related to. This would have made it possible to register an algorithm but reserve it from being used, in order to (for example) try and maintain some parity with old digest. Needless to say, the original sketch design had flaws and we didn't go that way. Instead, the registry requires entries to be identified using a Structured Fields key, which makes the idea of a reserved status due to a key that can't be used rather strange. TL;DR lets remove the "reserved" status because it isn't used by anything already and doesn't have much logic behind how it would be used in future.
We need to evaluate and possibly pare down / adjust the flags in the frame, based upon real-world use cases. See Kazuho's evaluation: URL
I agree the need for evaluation. OTOH, I do not think we should pare down / adjust flags, since real-world use cases could change as time evolves. The way it is defined now represents the cache state as-is and I believe that it would be most resilient in the long term.
OK.


Roman Danyliw made some comments during IESG review related to receiver validation behaviour. RFC 3230 was quite relaxed about stating receiver requirements and we've followed suit by carrying over that normative langauge almost verbatim for Content-Digest and Repr-Digest. The intention has always been that applications are responsible for deciding what integrity checks are important and what validation failure means to them. Roman suggests that we make this intention more concrete by adding explicit statements. This seems like a good idea and I'll prepare a PR to this effect. Its a restatement of intent but it is new normative language, so I'll cross post to the HTTP WG list for any additional input.


Apologies in advance.
No apology needed. I stuttered over this same sentence yesterday when fixing an unrelated nit. I almost changed it then but didn't want to mix concerns. Given that somebody else has raised a comment and provided an alternative I agree with, leads me to believe its worth fixing. Thanks.
Much cleaner, +1


Update example domain names to avoid "example-URL" and too-long lines
Some examples use ; IDNITS dings you for not using . Should probably use something like .
The examples in 2.1 have lines that are too long. Because it's caused by , which is a String, I think your options are: Shorten the strings Use RFC 8792 line wrapping


From Ilari Liusvaara on the : From NAME on the :
Maybe also consider for identification. That's not perfect, because of the "none" thing, but it might be a better fit. The TLS schemes are generally OK provided that you only use the recommended ones (of which there aren't many).
I don't love JWA since , but using TLS SignatureScheme with a requirement to only use the recommended ones sounds good to me.
NAME Doesn't it define the algorithm and then define the subkey types and in ?
NAME that could be made to work though it's quite clunky since it requires a separate string parameter for "alg". Overall I think the is a much better fit for signatures here. We already tightly integrate with TLS but not JWA. All that said, the closest option for hashes is the and that's been orphaned by RFC 8447. At this point I guess we should bite the bullet and define a new registry. Perhaps we include as current values: hmac-sha256 hmac-sha384 hmac-sha512 signature-rsapkcs1sha256 signature-rsapkcs1sha384 signature-rsapkcs1sha512 signature-ecdsasecp256r1sha256 signature-ecdsasecp384r1sha384 signature-ecdsasecp521r1sha512 signature-rsapssrsaesha256 signature-rsapssrsaesha384 signature-rsapssrsaesha512 signature-rsapsspsssha256 signature-rsapsspsssha384 signature-rsapsspsssha512 signature-ed25519 signature-ed448 Of course this requires to paint the bikeshed one of two colors: HMAC and Signatures in the same registry, using a single new auth scheme Separate registries, using separate auth schemes Thoughts? At this point I suspect this issue will need WG discussion at IETF 116.
I had to implement rsapsspss_shaX algorithms to produce test vectors for DCs, and unless there's a really compelling reason to include them, I'd really rather not. They're just such a pain to use, and the support for them is very poor (thus me needing to implement them).
FWIW, adding an entry in the registry doesn't mean it'll be mandatory to implement so there's not much of a cost. But I don't feel strongly about this one so I'm happy to not include it if it's the WG's preference.
Just saying here's a registry that you might could co-opt: URL Defined by URL
This is an existing registry of hash algorithms with string identifiers: URL Defined by URL
Discussed at IETF 116, sense of the room appeared to be that removing the HMAC feature entirely and switching to the TLS SignatureScheme registry for signatures was the simplest solution here.
OK wrote up to address this
Is there a technical reason why the header was not chosen for this draft? That can be sent without a corresponding challenge (in an unprompted way), as we note in the . It seems like that would work in this context, too.
Is this rather about using the Authorization header?
Yep!
NAME can you elaborate on "as we note in the "? I skimmed through that draft and it seems to clearly require a TokenChallenge before sending a Token.
I thought we had text that described it, but I can't find it. In any case, I think one can send the Authorization header unsolicited, so I think this draft ought to do that instead of rolling a new auth header.
Fair enough, let's discuss this at 116.
FWIW, I agree that unprompted "Authorization" is permissible in this context, but I think "Unprompted-Authorization" could be useful for clarity when reading logs, etc.
Discussed at IETF 116, sense of the room appeared to be that switching to Authorization made sense.
OK wrote up to address this


NAME that should already be covered by the last paragraph in this section. In particular the format is the Port is quite explicit there. Are you saying we should mention that strings are in ASCII?
No, sorry, I'm talking about the host name in particular. There was a long back and forth with Paul about the format of this field (is it the thing that appears in the HTTP request authority header, the thing that appears in the TLS SNI, etc), and we ended up being explicit. Just trying to save you some trouble down the road.
Oh, thanks. I agree we should be explicit. Could you point me to the specific text in Privacy Pass for this please?
Found the suggested Privacy Pass text and added to this PR.
I would recommend making the TLS exporter labels specific to the type of algorithm in use. For example, rather than use "EXPORTER-HTTP-Unprompted-Authentication-Signature" for signature-based authenticators, I might use "EXPORTER-HTTP-Unprompted-Authentication-Signature-Ed25519" for authenticators using Ed25519.
This would seem to have the drawback of making it complicated for intermediates to forward the authentication nonce. The alternative being for intermediary to implement the validation itself, which has its own drawbacks. Thinking why would one want to do something like this, I came up with vague ideas about possible cross-key tracking vectors. However, making labels algorithm-specific would not help if both keys happen to have the same type. One idea would be to mix the key id as context input, which would make the nonces be pretty much per-key in a way that is feasible for the first intermediary to calculate with no explicit algorithm support nor configuration.
An alternative proposal would be to just use a single context string for exporting the nonce but then somehow bind additional information into the signature computation at a higher layer. This would address the issue without complicating the intermediary story, I think.
Any case that involves intermediaries forwarding tokens will necessarily involve some amount of trust in the intermediary. The intermediary can provide the exporter output when it forwards the token, which would allow the signature to be verified, but the recipient is going to have to trust that this isn't copied from some other request. I definitely think that the context string is the right place to include origin, key identifier, algorithm choice, and maybe even some context from the request (URL). That latter depends on how heavily people intend to lean on the intermediation case.
Discussed at IETF 116, sense of the room appeared to be that adding the key identifier and algorithm to the context made sense. We can skip URL and instead add realm, see
OK wrote up to address this
signatures are computed in a way that binds them to the origin which accepts the authenticator. While it's true that the nonce is a per-session concept, and the session is bound to a specific origin (by virtue of the TLS SNI), it seems possible for bugs to be introduced in settings where a TLS-terminating server supports more than one origin. Maybe the server accidentally sends an authenticator computed in a session for one origin to another, or something. I would follow in WebAuthn's footsteps here and sign something that's specific to the origin.
HTTPS sessions are not bound to a specific origin. There is no requirement for client to only use one origin on connection, and even if there was, TLS SNI is not fine-grained enough, as e.g. https://foo.example and https://foo.example:8443 are different origins, but have the same TLS SNI. Extending the idea of throwing some stuff into the context from httpwg/http-extensions, one could throw the origin (host/:authority) in as well (the contexts can be up to 65535 bytes, so there is plenty of space). This would bind the signatures to origin, would still work if host gets remapped somewhere, and could mitigate some tracking vectors. And it would still retain the no explicit configuration / no algorithm support property.
Oh, right, duh. We have connection coalescing! Throwing in the origin as you suggest seems like it work, and as in httpwg/http-extensions perhaps doing it above nonce generation is best.
Discussed at IETF 116, it seemed like the proposal most likely to succeed was to add the to the context
Regarding the question on , asking if origin and also URL should be part of the context. says, quote "unless specifically allowed by the authentication scheme, a single protection space cannot extend outside the scope of its server." So as NAME points out, we should include the origin. discusses the danger of using the same context for different URLs belonging to the same origin, pointing out that it is an problem that already exists and explaining the mitigations (such as not forwarding the Authorization header to the application running on top of HTTP). Assuming that we would switch to using the Authorization header, I think we can rely on that. To paraphrase, there is no need to include URL in the context. In addition, we can1 include "realm" in the Context, so that there can be multiple "protection spaces" inside one origin. In the Unprompted Authentication scheme, there is no way for a server to signal the realm to be used. Therefore, as NAME pointed out, there has to be a default value that would be defined by the specification. Clients and servers can agree out-of-band to use a different value. 1: During the meeting, I asked as a pure question how Realm is to be used. In the follow-on discussion at least assumed that "realm" has to be part of the Unprompted Authentication as it is to use the Authorization header. However, reading RFC 9110 I realize that not all authentication schemes are required to support realms (i.e., having multiple protection spaces within an origin). Hence the "can."
OK wrote up to address this
This is a good change, but to avoid future nit picking I might clarify what are the types of each field in the context. For example, is the port an integer in network byte order? What is the format of the host string? We just went through a whole kerfuffle in Privacy Pass on this point, and my advice would be to address it early.


In the current draft, the header is composed as: The server computes the nonce from the TLS key material exporter and verifies the signature. This doesn't actually guarantee freshness, because its possible for parties to construct signatures which are valid for any message/nonce. This means that a party which does not have access to the TLS Export material can still inject a valid Auth header. I don't think that's a major problem, but it is a bit unintuitive and its hard to predict how drafts like this will eventually get deployed. A simple fix would be in to add an additional parameter, say which is or similar and have servers check its been correctly computed. This ensures that only parties that can access TLS key material can inject valid headers. Behind the scenes, this attack / fix works because hash functions have to be collision resistant for all inputs, whereas signatures don't have to satisfy any properties if the associated public key was generated maliciously. has a longer discussion.
Thanks! This sounds like an easy fix. Instead of a hash, we could also generate more bytes from the key exporter and use some for the nonce and some for the parameter
Wrote up to fix this


From Ilari Liusvaara on the :
I think that I might disagree with Ilari here for this application. Key separation is probably a better model to employ here, though as soon as someone even hints that they might want to share client certificate keys and these keys then this sort of protection probably makes sense.
Briefly mentioned this issue at IETF 116, but did not have time for questions so we asked folks who care to comment on the issue.
Thinking about this some more, prepending a fixed string to the nonce before signing it sounds like it would be pretty cheap and would remove a class of issues - I'm inclined to do that. I'll write up a PR.
OK wrote up to address this


During the SEC AD review, a DISCUSS was raised about the current status values. This change modifies the values to better align with Signatures. The guidance for registration and/or usage of an algorithm based on the status is not affected.


Looks good except for minor details and potentially a bug (encoding vs decoding). I'd also like to see the spec enforce a consistent form of percent encoding (lower vs upper)
I am sceptical wrt "use the URI percent encoder". The reason being: percent encoding rules depend on what part of the URI needs encoding (and many APIs do not get that) calling the API for a single character multiple times usually requires converting a char to a string, and that might not be good for perf if we really care about that
I've removed the reliance on URI for percent encoding; was clean as NAME said it would be. Regarding case -- NAME RFC4648 Section 8 is explicitly case-insensitive. Given that and the discussion in the group yesterday, I've left this case-insensitive. Say if you still disagree.
NAME , I was suggesting an inline definition. The fact that uppercase is base16 would just be an observation (and not a particularly useful one). Lowercase tends to be the default mode in several places.
NAME it wasn't at all clear that's what you were suggesting. I'll make an attempt.
Looking at it, I think I prefer referring to 4648. This this addresses the original issue, I'll merge; if someone wants to propose an alternate way to specify this, please feel free to open a PR.
As currently defined, the two serialized DisplayStrings %"foo\"bla%22bar" and %"foo%22bla\"bar" are semantically identical. We should either use %-escapes or \-escapes, mixing them this way is asking for smuggling-attacks.
I think probably -escapes; will work up a PR.
I don't believe that relying on a different RFC for the hex encoding makes this much better (so I sort of disagree with Martin's proposal). Just define the escaping exactly inline, and then we can choose upper/lower.


Closes URL I am not super sure about the wording here, but this is a start. The sentences seem quite long and maybe the rules could also be expressed in fewer words.
I wonder if it is also possible to expose this final upload size in the response to Offset Retrieving Procedures. I don't think we can set in the HEAD responses because that would indicate that the server already has this amount of bytes, which is not correct.
If the client acknowledged its final upload size at any point ( + ), it should still know it in the future, so I don't think we need a way for the server to echo it in the offset retrieving response. If the server disagrees with the client, then someone's data representation has changed, and we shouldn't continue the upload anyway.
Looks good. Wondering if these could be reduced to SHOULDs though. It wouldn't really affect interop if the server didn't implement this.
Fair point, let's leave such functionality out of the draft. While it is true that clients usually won't really notice if the server does or does not support this, I think we can be stricter here and require this additional safety catch here. It will help to create a more standard landscape of resumable upload servers. Unless there is something against requiring this, we can keep it a MUST IMO.
I just updated this PR to use the Upload-Complete header as agreed on in
The arguments for SHOULD are: This check requires additional code and complexity. MUSTs are situations that a minimal implementation has to handle anyway and we are just strict about how to handle them. For people using chunked uploads, this check is only useful if the last chunk is interrupted which is sort of an edge case. Maybe we can generalize the check if we adopt ranged PATCH. I don't have a strong opinion on this, so either way is OK with me.
When the server receives a series of appends: If the offset+length is inconsistent, the server should reject the upload.
To clarify; Is what you are saying here that the provided during the upload creation procedure should act as the total size of the file, similar to Upload-Length in tus1x?
I am not sure if we want this. I ran into this exact problem because your NIOResumableUpload implementation uses this logic (see URL). We currently have the header to indicate the completeness of the upload. Based on this information, the server can determine if an upload is complete or not without relying on . Adding to the upload logic would mean that we have two indicators for upload completeness, which could potentially disagree with each other. Personally, I think we should not use to determine the upload's completeness and only determine it based on whether the client set in a successful request. For each Upload Creation Procedure or Upload Appending Procedure, the should be set to the number of bytes that the client wants to send in this individual procedure. For example, if you want to transmit 100 bytes in the first POST request, set (or not if you use ). If you want to transmit 200 bytes in the following PATCH request, set . If you want to finish the upload then, set and the upload is considered complete with its 300 bytes of content.
The issue in NIOResumableUpload was a bug, not how this is supposed to work. Offset + Content-Length = final upload size when the upload is complete, and if the client has told the server about the final size, it shouldn't be allowed to change its mind.
Echoing what Guoye said, should not determine the upload's completeness, but if an request has a , then the server can expect and enforce the final upload size based on that . This prevents a client from appending more bytes to their upload than the server anticipated. Ex. Client starts an upload , Server expects a final upload size of 100 bytes Upload is interrupted, offset-retrieving, server sends Client now tries to append an extra ~10GB Client sends , , Server can reject this request
I see, thanks for the explanation. That makes sense. Basically, in conjunction with let the server know the final upload size, which should not be changed
How does that work if the last append has in conjunction with . The Content-Length needs to match the number of bytes in the append message.
Final size = upload-offset + content-length if the upload is complete
So the first ever request with Upload-Incomplete: ?0 and content-length sets the expected final size. Every other request must have a content-length less than that value?
Yeah, once the final length is determined, it cannot be changed by subsequent requests.
OK I think that makes sense but it's not obvious from the spec. We should try and make it more accessible with some new or different text.
I started on the wording in


Based on discussions with NAME NAME and others, there are potential key confusion attacks when the server is checking the signature using the wrong public key. I think the simplest solution is to add the public key to the TLS key exporter. That should solve the issue without increasing the amount of bytes sent on the wire
Including the public key in the exporter context makes it significantly harder to implement the server side of this. Including the hash of the public key in the signature appears to work also. I have a sketch model in Tamarin that doesn't find any attacks when the hash of the public key is in the signature, which gives me some confidence that it's doable, although NAME wasn't convinced. We should discuss this in the room at 117.
I agree with NAME The implementation complexity that comes from putting the public key in the exporter context is real, at least for some edge networks. I think we should pursue alternatives that don't weaken the security properties, even if they make the registration step a bit more explicit.
If this design makes implementation hard then we should totally change it. Can I ask you to elaborate on what causes this to be hard on the server side?
The basic problem in our particular case is that the component that terminates TLS and computes exported values is upstream of the component that has the public key. So when a request comes in with the header to the TLS terminator, the public key needs to get relayed back for computation. If, instead, the public key was signed, then the TLS terminator could simply forward the computed exporter without any sort of round trip. (I punched this in on my phone, but can draw pictures on a laptop if the above is not clear.) We don't necessarily need to cater to one implementation, but I would be surprised if this were not a common arrangement in practice.
Thanks, that makes sense. To explore the problem space: if we were to include the public key in both the context and a header parameter, would that work for your implementation? (That way the TLS terminator can call the exporter without a round trip.)
Yep, that would address the problem too.
SIGMA seems like it might be worth considering as an alternative. That is, sign the nonce, but then include a MAC that covers all of the relevant parameters.
Something like SIGMA should also work, but I'd like to minimize the number of primitives required to implement this. Currently, modifying an HTTPS stack to support this draft only requires a signature implementation and a TLS key exporter API. Using a MAC would require a MAC primitive and opens the question "which MAC should we use?"
That's an easy question: you are using HKDF to get the values, so HMAC is a logical choice. The only reason I suggested that is that I'm increasingly nervous about these bespoke constructions. We understand what sign and mac provides.
I think we need to first identify what property it is we actually want, and then see what is the simplest way to get there. NAME what is the property we want?
NAME had a long chat about this today. We didn't come to any solid conclusions - the authentication property here is really subtle and the attacker model not yet clear. This is going to need some really careful work and detailed formal analysis to get right. In terms of this discussion, my personal take would be: I don't think a mac & sign approach is going to give you anything strictly better or different than an exporter + signature approach. In both cases its just a question of what you put in the exporter / mac. Having the public key conveyed in the header and bound explicitly in the exporter (rather than via the keyid) seems like a conservative and reasonable approach.
Thanks for thinking through this! I've written up to add the public key to both the context and the header


Allow the original name of the next hop to be the start of the list, and add an example.
NAME NAME please review!
LGTM
I understand that the current draft is specifically targeting forward proxies, but as currently described, the is missing some information when used by reverse proxies, and it's not self-contained anymore (i.e. the requested/configured next hop is not part of the field), making debugging much harder. I find the fact that is not included here a bit confusing. While operators or clients connecting directly to might know that it's a forward proxy and could infer that was the requested hostname, the clients that are a few hops away from it, won't know this, and might be surprised how the and other aliases got in there. Furthermore, in a similar scenario with a client connecting to the reverse proxy and requesting , which is configured to use as the backend, that response is missing the most critical piece of information, and instead of helping, it adds more confusion. As such, I'd suggest that the requested/configured hostname should be included as the first entry in , especially when points to the resolved IP address. cc NAME NAME
This is a good point, especially for reverse proxies. The name of the next hop could be in the next-hop parameter itself, but then there is a choice between the address and the name there. For forward proxies, the name is known and the address is interesting. For reverse proxies, i imagine the name of the next hop is more useful than the address, but I can see why both could be wanted. In such case, perhaps we can allow the aliases list to include the next hop name if it differs from the authority requested by the client.
Yes, that's unfortunate. I'm not sure how we've missed this in RFC 9209. Perhaps we could allow both and use for the configured next hop name, and for the resolved IP address... which actually matches what I'm suggesting we do here by including the requested/configured name as the first entry in . But that's only true on the first hop, right? The authority could be changed along the way by intermediaries, and then the original client wouldn't know what started the resolution which resulted in the received . How would the original client know if that happened in a long chain of proxies? The authority requested by the client connecting to is not included in the header, and therefore it's not known to the original client. It's impossible to tell if that entry was generated by a proxy that was configured to connect to , which also happens to be the authority it received and therefore it's not included in , or if it was configured to connect to . Basically, I'm trying to avoid adding ambiguity and guesswork to the debugging process that uses this header.
Upon discussing in person: Good to add to an example The text should make it clear that the original name is allowed to be at the start of the list (but doesn't strictly need to be included)


Within TLS 1.3, the only options for 0-RTT are "accept" or "reject". "accept but delay until after the handshake" is not visible within the TLS 1.3 protocol. The current draft language doesn't align nicely with this, and should be adjusted. Credit: NAME


Closes URL
NAME brought up that during the WG meeting that reusing Upload-Complete on requests and responses can be confusing. They don’t mean exactly the same thing: on the server means it has received the full upload, while on the client means the body it will send is a complete upload.
We discussed this internally and prepared a response: Upload-Complete is used on both requests and responses because it is symmetrical. Upon a typical successful transaction, an request results in an response, and an request results in an response. A server implementation can simply echo the field. However, they are also meanings that we can take advantage of. The presence on the request means it’s a resumable request, and the presence on the response is also a useful signal. Since we are upgrading regular uploads, there are cases where 4xx/5xx responses are intentional and we can't just eat it by attempting to resume. We would be much more confident that the response came from the real server rather than a middlebox which shouldn’t randomly add . The server can also use to terminate a request early if it does not care about the body, similar to the early response mechanism in HTTP/3.
I am having second thoughts about this as well. While debugging a server implementation, the naming of the headers also confused me for a moment (even though I wrote parts of the draft). The reason is that in a response (or how it is currently called) refers to the current state of the upload, while in a request refers to the potential state in the future, if the request completed successfully. I don't think that we have a general issue with the concept of and have to change much. But maybe a simple name change can help here already to alleviate the confusion. We could use for the response header to indicate that it represents the current state. And for request headers to indicate that process the request successfully will complete the upload. We loose the symmetry of the names in request and response, but maybe this makes their relation even clearer.
I think for both client and server works because it represents their own perspectives of the upload. For the client, sending means "the upload is complete on my end, I've included all the data to complete it." The client isn't making assumptions about whether the server has received all the data; it's only expressing to the server that from its perspective, the upload data supplied is now whole. For the server, responding acknowledges the client's view of the complete upload and says, "Yes, the upload is complete on my end, too." Same goes for .
At IETF 117, we agreed on using for requests and responses: URL I will open a PR for this and then we can close this issue.


Can I suggest we use 'converted' instead of 'normalized' ?
WFM, will update.
It's annoying to test for otherwise. Still allow both cases in parse.
Postel's law ("Be liberal in what you accept, and conservative in what you send.") isn't as popular these days as it once was. Not sure we need to accept upper case % anymore.
I am sure that we don’t. (Though I have thoughts on the use of the Robustness Principle to guide this sort of decision. Generally, it is better to look at what the case needs. Here, the values are created by code, so permissiveness is not a valuable feature.)
Fine. See URL


I tried to make this work, but NAME is right: this is entirely a transport decision and given that our best option was to violate a MUST in RFC 7230, that's too hard. This just says that HTTP/1.1 is no good because we can't include the scheme (because RFC 7230 says we can't). I almost made this h2-specific, but then remembered that there might be another protocol that has favourable properties.
It's official - MT says "HTTP/1.1 is no good."


This switches the custom wildcard matching to use with regexp support disabled. URLPattern is being used by the service worker routing API's and is what the web side is standardizing on for anything that pattern-matches URLs. This splits the match pattern into explicit path and search (query param) components and forces the origin to be inherited from the dictionary request URL. Also included here is a new field for to allow for matching on request destinations. The biggest use case for that will be for allowing site-wide HTML dictionaries to do something like and for the dictionary to not be sent for every request across the site (images, etc). See issues , ,