Abstract This document provides usage guidance for external Pre-Shared Keys <del> (PSKs) in Transport Layer Security (TLS) version 1.3 as defined in RFC 8446.  It lists TLS security properties provided by PSKs under certain assumptions and demonstrates how violations of these assumptions lead to attacks.  It discusses PSK use cases, provisioning processes, and TLS stack implementation support in the context of these assumptions.  It provides advice for applications in various use cases to help meet these assumptions.  It also lists the privacy and security properties that are not provided by TLS when external PSKs are used. </del>  1. This document provides guidance on the use of external Pre-Shared <del> Keys (PSKs) in Transport Layer Security (TLS) version 1.3 RFC8446. This document lists TLS security properties provided by PSKs under certain assumptions and demonstrates how violations of these assumptions lead to attacks.  This document discusses PSK use cases, provisioning processes, and TLS stack implementation support in the context of these assumptions.  This document also provides advice for applications in various use cases to help meet these assumptions. </del>  There are many resources that provide guidance for password generation and verification aimed towards improving security. However, there is no such equivalent for external Pre-Shared Keys (PSKs) in TLS.  This document aims to reduce that gap. <del> The guidance provided in this document is applicable across TLS RFC8446, DTLS I-D.ietf-tls-dtls13, and Compact TLS I-D.ietf-tls-ctls. </del> 2. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 4. <del> External PSK authentication in TLS allows endpoints to authenticate connections using previously established keys.  These keys do not provide protection of endpoint identities (see endpoint-privacy), nor do they provide non-repudiation (one endpoint in a connection can deny the conversation).  Protection of endpoint identities and protection against an endpoint denying the conversation are possible when a fresh TLS handshake is performed. </del>  PSK authentication security implicitly assumes one fundamental property: each PSK is known to exactly one client and one server, and Any group member can impersonate any other group member. <del> If PSK with DH is used, then compromise of a group member that actively completes connections with other group members can read (and modify) traffic. </del>  <del> If PSK without DH is used, then compromise of any group member allows the attacker to passively read (and modify) all traffic. If a group member is compromised, then the attacker can perform all of the above attacks. </del>  Additionally, a malicious non-member can reroute handshakes between honest group members to connect them in unintended ways, as described <del> below.  Note that this class of attack is not possible if each member uses the SNI extension RFC6066 and terminates the connection on mismatch between the presented SNI value and the receiving member's known identity.  See Selfie for details. </del>  To illustrate the rerouting attack, consider the group of peers who know the PSK be "A", "B", and "C".  The attack proceeds as follows: The attacker redirects the "Finished" message to "C".  "C" has completed the handshake with "A". <del> This attack violates the peer authentication property, and if "C" supports a weaker set of cipher suites than "B", this attack also violates the downgrade protection property.  This rerouting is a type of identity misbinding attack Sethi.  Selfie attack Selfie is a </del>  special case of the rerouting attack against a group member that can act both as TLS server and client.  In the Selfie attack, a malicious non-member reroutes a connection from the client to the server on the incorporating EPSKs described in I-D.ietf-tls-external-psk- importer. <del> Unless other accommodations are made, each PSK MUST be restricted in its use to at most two logical nodes: one logical node in a TLS client role and one logical node in a TLS server role.  (The two logical nodes MAY be the same, in different roles.)  Two acceptable accommodations are described in I-D.ietf-tls-external- psk-importer: (1) exchanging client and server identifiers over the TLS connection after the handshake, and (2) incorporating identifiers for both the client and the server into the context string for an EPSK importer. </del>  Nodes using TLS 1.3 SHOULD use external PSK importers I-D.ietf- tls-external-psk-importer when configuring PSKs for a client- 8.  It is NOT RECOMMENDED to share the same PSK between more than one client and server.  However, as discussed in use-cases, there are application scenarios that may rely on sharing the same PSK among

This deals with many comments from the AD Evaluation. The comment on section 6.1 still needs to be resolved, and the NITS need to be addressed.
Chris's suggestions generally seem reasonable

Abstract This document provides usage guidance for external Pre-Shared Keys  <ins> (PSKs) in Transport Layer Security (TLS) 1.3 as defined in RFC 8446. This document lists TLS security properties provided by PSKs under certain assumptions, and then demonstrates how violations of these assumptions lead to attacks.  This document discusses PSK use cases and provisioning processes.  This document provides advice for applications to help meet these assumptions.  This document also lists the privacy and security properties that are not provided by TLS 1.3 when external PSKs are used. </ins> 1. This document provides guidance on the use of external Pre-Shared  <ins> Keys (PSKs) in Transport Layer Security (TLS) 1.3 RFC8446.  This guidance also applies to Datagram TLS (DTLS) 1.3 I-D.ietf-tls-dtls13 and Compact TLS 1.3 I-D.ietf-tls-ctls.  For readability, this document uses the term TLS to refer to all such versions.  External PSKs are symmetric secret keys provided to the TLS protocol implementation as external inputs.  External PSKs are provisioned out-of-band.  This document lists TLS security properties provided by PSKs under certain assumptions and demonstrates how violations of these assumptions lead to attacks.  This document discusses PSK use cases, provisioning processes, and TLS stack implementation support in the context of these assumptions.  This document also provides advice for applications in various use cases to help meet these assumptions. </ins> There are many resources that provide guidance for password generation and verification aimed towards improving security. However, there is no such equivalent for external Pre-Shared Keys (PSKs) in TLS.  This document aims to reduce that gap.  2. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 4.  <ins> When using external PSK authentication, the use of previously established PSKs allows TLS endpoints to authenticate the endpoint identities.  However, these keys do not provide privacy protection of endpoint identities (see endpoint-privacy), nor do they provide non- repudiation (one endpoint in a connection can deny the conversation). Protection of endpoint identities and protection against an endpoint denying the conversation are possible only when a fresh TLS handshake that authenticates the endpoints with certificates is performed. </ins> PSK authentication security implicitly assumes one fundamental property: each PSK is known to exactly one client and one server, and Any group member can impersonate any other group member.  <ins> If PSK is combined with DH, then compromise of a group member that knows the resulting DH shared secret will enable the attacker to read (and modify) traffic. </ins>  <ins> If PSK is not combined with DH, then compromise of any group member allows the attacker to passively read (and actively modify) all traffic. </ins> Additionally, a malicious non-member can reroute handshakes between honest group members to connect them in unintended ways, as described  <ins> below.  Note that a partial mitigiation against this class of attack is available: each group member includes the SNI extension RFC6066 and terminates the connection on mismatch between the presented SNI value and the receiving member's known identity.  See Selfie for details. </ins> To illustrate the rerouting attack, consider the group of peers who know the PSK be "A", "B", and "C".  The attack proceeds as follows: The attacker redirects the "Finished" message to "C".  "C" has completed the handshake with "A".  <ins> In this attack, peer authentication is not provided.  Also, if "C" supports a weaker set of cipher suites than "B", cryptographic algorithm downgrade attacks might be possible.  This rerouting is a type of identity misbinding attack Sethi.  Selfie attack Selfie is a </ins> special case of the rerouting attack against a group member that can act both as TLS server and client.  In the Selfie attack, a malicious non-member reroutes a connection from the client to the server on the incorporating EPSKs described in I-D.ietf-tls-external-psk- importer.  <ins> Unless other accommodations are made to mitigate the risks of PSKs know to a group, each PSK MUST be restricted in its use to at most two logical nodes: one logical node in a TLS client role and one logical node in a TLS server role.  (The two logical nodes MAY be the same, in different roles.)  Two acceptable accommodations are described in I-D.ietf-tls-external-psk-importer: (1) exchanging client and server identifiers over the TLS connection after the handshake, and (2) incorporating identifiers for both the client and the server into the context string for an EPSK importer. </ins> Nodes using TLS 1.3 SHOULD use external PSK importers I-D.ietf- tls-external-psk-importer when configuring PSKs for a client- 8. <ins> Security considerations are provided throughout this document.  It bears repeating that there are concerns related to the use of external PSKs regarding proper identification of TLS 1.3 endpoints and additional risks when external PSKs are known to a group. </ins> It is NOT RECOMMENDED to share the same PSK between more than one client and server.  However, as discussed in use-cases, there are application scenarios that may rely on sharing the same PSK among


4. <del> When using external PSK authentication, the use of previously established PSKs allows TLS endpoints to authenticate the endpoint identities.  However, these keys do not provide privacy protection of endpoint identities (see endpoint-privacy), nor do they provide non- repudiation (one endpoint in a connection can deny the conversation). </del>  PSK authentication security implicitly assumes one fundamental property: each PSK is known to exactly one client and one server, and 4.1. <del> As discussed in use-cases, there are use cases where it is desirable for multiple clients or multiple servers to share a PSK.  If this is done naively by having all members share a common key, then TLS authenticates only group membership, and the security of the overall system is inherently rather brittle.  There are a number of obvious weaknesses here: </del>  Any group member can impersonate any other group member. <del> If PSK is combined with DH, then compromise of a group member that knows the resulting DH shared secret will enable the attacker to passively read (and actively modify) traffic. </del>  <del> If PSK is not combined with DH, then compromise of any group member allows the attacker to passively read (and actively modify) all traffic. </del>  Additionally, a malicious non-member can reroute handshakes between honest group members to connect them in unintended ways, as described 4.2. Entropy properties of external PSKs may also affect TLS security <del> properties.  In particular, if a high entropy PSK is used, then PSK- only key establishment modes are secure against both active and passive attack.  However, they lack forward security.  Forward security may be achieved by using a PSK-DH mode. </del>  In contrast, if a low entropy PSK is used, then PSK-only key establishment modes are subject to passive exhaustive search attacks computers. There are also use cases where PSKs are shared between more than two <del> entities.  Some examples below (as noted by Akhmetzyanova et al.Akhmetzyanova): </del>  Group chats.  In this use-case, group participants may be provisioned an external PSK out-of-band for establishing follows: Each PSK SHOULD be derived from at least 128 bits of entropy, MUST <del> be at least 128 bits long, and SHOULD be combined with a DH exchange, e.g., by using the "psk_dhe_ke" Pre-Shared Key Exchange Mode in TLS 1.3, for forward secrecy.  As discussed in sec- properties, low entropy PSKs, i.e., those derived from less than 128 bits of entropy, are subject to attack and SHOULD be avoided. If only low-entropy keys are available, then key establishment mechanisms such as Password Authenticated Key Exchange (PAKE) that mitigate the risk of offline dictionary attacks SHOULD be employed.  Note that no such mechanisms have yet been standardised, and further that these mechanisms will not </del>  necessarily follow the same architecture as the process for incorporating external PSKs described in I-D.ietf-tls-external- psk-importer.

NIT: Might be better to say: Just drops some redundant words.
I think some things that should be more positive: -- For both PSK authentication and PSK key exchange without (EC)DHE the bad security properties such as lack of identity protection and lack of forward secrecy can be overcome by using one-time PSKs. External PSKs with short lifetimes are quite common in many real deployments. I think this should be mentioned. -- I think quantum resistance should be mentioned earlier in the document. Quantum resistance is a security property, not use a use case. Some things that should be more negative: -- In the list in 4.1 you can add "4. Any group member can blame any other group member." Other comments: -- "then PSK-only key establishment modes are secure against both active and passive attack." I think this you need to describe the exact attacks you have in mind rather than use the work "secure". My view would be that acceptable security in 2021 includes both identity protection and forward secrecy. But more on a system level, then necessarily by TLS itself. -- "DH" I think it would be good to change all “DH” to “DHE” and all “Diffie-Hellman” to “ephemeral Diffie-Hellman” to avoid confusion with the static DH cipher suites in obsolete versions of TLS. -- "As discussed in Section 6, there are use cases where it is desirable for multiple clients or multiple servers to share a PSK." "However, as discussed in Section 6, there are application scenarios that may rely on sharing the same PSK among multiple nodes." Unless you have any real deployments to share, I think this should be reformulated. These are Gedankenexperiments used to illustrate the attack, not real-world applications. I would reformulate and remove "desirable", group PSKs should be very much discouraged. Suggestion: "As discussed in Section 6, to illustrate their attack, [Akhmetzyanova] describes scenarios where multiple clients or multiple servers share a PSK."

4.  <ins> The use of a previously established PSK allows TLS nodes to authenticate the endpoint identities.  It also offers other benefits, including resistance to attacks in presence of quantum computes; see entropy for related discussion.  However, these keys do not provide privacy protection of endpoint identities, nor do they provide non- repudiation (one endpoint in a connection can deny the conversation); see endpoint-privacy for related discussion. </ins> PSK authentication security implicitly assumes one fundamental property: each PSK is known to exactly one client and one server, and 4.1.  <ins> As discussed in use-cases, to demonstrate their attack, AASS19 describes scenarios where multiple clients or multiple servers share a PSK.  If this is done naively by having all members share a common key, then TLS authenticates only group membership, and the security of the overall system is inherently rather brittle.  There are a number of obvious weaknesses here: </ins> Any group member can impersonate any other group member.  <ins> If PSK is combined with a fresh ephemeral key exchange, then compromise of a group member that knows the resulting shared secret will enable the attacker to passively read (and actively modify) traffic. </ins>  <ins> If PSK is not combined with fresh ephemeral key exchange, then compromise of any group member allows the attacker to passively read (and actively modify) all traffic. </ins> Additionally, a malicious non-member can reroute handshakes between honest group members to connect them in unintended ways, as described 4.2. Entropy properties of external PSKs may also affect TLS security  <ins> properties.  For example, if a high entropy PSK is used, then PSK- only key establishment modes provide expected security properties for TLS, including, for example, including establishing the same session keys between peers, secrecy of session keys, peer authentication, and downgrade protection.  See RFC8446, Section E.1 for an explanation of these properties.  However, these modes lack forward security. Forward security may be achieved by using a PSK-DH mode, or, alternatively, by using PSKs with short lifetimes. </ins> In contrast, if a low entropy PSK is used, then PSK-only key establishment modes are subject to passive exhaustive search attacks computers. There are also use cases where PSKs are shared between more than two  <ins> entities.  Some examples below (as noted by Akhmetzyanova et al. AASS19): </ins> Group chats.  In this use-case, group participants may be provisioned an external PSK out-of-band for establishing follows: Each PSK SHOULD be derived from at least 128 bits of entropy, MUST  <ins> be at least 128 bits long, and SHOULD be combined with an ephemeral key exchange exchange, e.g., by using the "psk_dhe_ke" Pre-Shared Key Exchange Mode in TLS 1.3, for forward secrecy.  As discussed in sec-properties, low entropy PSKs, i.e., those derived from less than 128 bits of entropy, are subject to attack and SHOULD be avoided.  If only low-entropy keys are available, then key establishment mechanisms such as Password Authenticated Key Exchange (PAKE) that mitigate the risk of offline dictionary attacks SHOULD be employed.  Note that no such mechanisms have yet been standardised, and further that these mechanisms will not </ins> necessarily follow the same architecture as the process for incorporating external PSKs described in I-D.ietf-tls-external- psk-importer.


6. <del> PSK ciphersuites were first specified for TLS in 2005.  Now, PSKs are </del>  an integral part of the TLS version 1.3 specification RFC8446.  TLS 1.3 also uses PSKs for session resumption.  It distinguishes these resumption PSKs from external PSKs which have been provisioned out- <del> of-band (OOB).  Below, we list some example use-cases where pair-wise external PSKs (i.e., external PSKs that are shared between only one server and one client) have been used for authentication in TLS. </del>  Device-to-device communication with out-of-band synchronized keys. PSKs provisioned out-of-band for communicating with known Intra-data-center communication.  Machine-to-machine communication within a single data center or PoP may use externally provisioned PSKs, primarily for the purposes of supporting TLS connections <del> with early data. </del>  Certificateless server-to-server communication.  Machine-to- machine communication may use externally provisioned PSKs, to Machine Technical Specification LwM2M states that LwM2M servers MUST support the PSK mode of DTLS. <del> Use of PSK ciphersuites are optional when securing RADIUS RFC2865 with TLS as specified in RFC6614. </del>  <del> The Generic Authentication Architecture (GAA) defined by 3GGP mentions that TLS-PSK can be used between a server and user equipment for authentication GAA. </del>  Smart Cards.  The electronic German ID (eID) card supports authentication of a card holder to online services with TLS-PSK SmartCard. <del> Quantum resistance: Some deployments may use PSKs (or combine them with certificate-based authentication as described in RFC8773) because of the protection they provide against quantum computers. </del>  There are also use cases where PSKs are shared between more than two entities.  Some examples below (as noted by Akhmetzyanova et a central server (n keys for n devices), or have pairwise keys for communicating with each other (n^2 keys for n devices).  The exact provisioning process depends on the system requirements and threat model.  Whenever possible, avoid sharing a PSK between nodes; however, sharing a PSK among several node is sometimes unavoidable. When PSK sharing happens, other accommodations SHOULD be used as discussed in recommendations. <del> 6.1. </del>  Many industrial protocols assume that PSKs are distributed and assigned manually via one of the following approaches: typing the secrets may be printed on labels or included in a Bill of Materials for ease of scanning or import. <del> 6.2. </del>  PSK provisioning systems are often constrained in application- specific ways.  For example, although one goal of provisioning is to however important to remember that endpoints sharing the same group PSK can always impersonate each other.  9. This document makes no IANA requests.

While trying to find a home for this text, I did some other unrelated cleanup. I couldn't find a spot better than the security considerations. cc NAME
Slightly different placement than I suggested, but it works too.
From NAME This is a great point. We can add some language which describes considerations for external PSK reuse with early data.
Martin: I think we should add: When early data is used with an external PSK, the random value in the ClientHello is the only source of entropy that makes the keying material for the early data associated with one session different from the keying material for the early data associated win another session. As a result, when the external PSK is used more than one time, the random number source on the client has a significant role in the protection of the early data. However, this does not address the last point. Early data always has replay concerns. This was discussed at length during the development of RFC 8446. This is the reason that RFC 8446 says that clients "MUST only send early data which they deem safe to be replayed." With that warning in RFC 8446, what more needs to be said here?
Not sure what you mean regarding the last point, but this is a good contribution. How about (copy editing only):
That reads pretty well to me. Thanks, NAME
MT's text also looks good to me. I'm not sure I understand the (as-yet-unaddressed) point about anti-replay performance, though. I mean, I can parse it -- it's a claim that (some? all?) anti-replay implementations will incur more runtime cost than in scenarios where the PSK is reused and the random data is "not good enough". But how would that come to happen? Are we imagining an implementation that uses a hash table and inputs the client random as the hash input, and "not good enough" randomness would cause unbalanced hashing? Or is the nature of the concern on a totally different axis?
Yeah, I think that we can let that point lie. The NSS anti-replay implementation is somewhat vulnerable to hash stacking, but the effect is that early data is accepted less often, it's not that server CPU cycles are wasted.

6.  <ins> PSK ciphersuites were first specified for TLS in 2005.  PSKs are now </ins> an integral part of the TLS version 1.3 specification RFC8446.  TLS 1.3 also uses PSKs for session resumption.  It distinguishes these resumption PSKs from external PSKs which have been provisioned out-  <ins> of-band.  This section describes known use cases and provisioning processes for external PSKs with TLS. 6.1. This section lists some example use-cases where pair-wise external PSKs, i.e., external PSKs that are shared between only one server and one client, have been used for authentication in TLS. </ins> Device-to-device communication with out-of-band synchronized keys. PSKs provisioned out-of-band for communicating with known Intra-data-center communication.  Machine-to-machine communication within a single data center or PoP may use externally provisioned PSKs, primarily for the purposes of supporting TLS connections  <ins> with early data; see security-con for considerations when using early data with external PSKs. </ins> Certificateless server-to-server communication.  Machine-to- machine communication may use externally provisioned PSKs, to Machine Technical Specification LwM2M states that LwM2M servers MUST support the PSK mode of DTLS.  <ins> Securing RADIUS RFC2865 with TLS.  PSK ciphersuites are optional for this use case, as specified in RFC6614. </ins>  <ins> 3GPP server to user equipment authentication.  The Generic Authentication Architecture (GAA) defined by 3GGP mentions that TLS-PSK ciphersuites can be used between server and user equipment for authentication GAA. </ins> Smart Cards.  The electronic German ID (eID) card supports authentication of a card holder to online services with TLS-PSK SmartCard.  <ins> Quantum resistance.  Some deployments may use PSKs (or combine them with certificate-based authentication as described in RFC8773) because of the protection they provide against quantum computers. </ins> There are also use cases where PSKs are shared between more than two entities.  Some examples below (as noted by Akhmetzyanova et a central server (n keys for n devices), or have pairwise keys for communicating with each other (n^2 keys for n devices). <ins> 6.2. </ins> The exact provisioning process depends on the system requirements and threat model.  Whenever possible, avoid sharing a PSK between nodes; however, sharing a PSK among several node is sometimes unavoidable. When PSK sharing happens, other accommodations SHOULD be used as discussed in recommendations.  <ins> Examples of PSK provisioning processes are included below. </ins> Many industrial protocols assume that PSKs are distributed and assigned manually via one of the following approaches: typing the secrets may be printed on labels or included in a Bill of Materials for ease of scanning or import.  <ins> 6.3. </ins> PSK provisioning systems are often constrained in application- specific ways.  For example, although one goal of provisioning is to however important to remember that endpoints sharing the same group PSK can always impersonate each other. <ins> Considerations for external PSK usage extend beynond proper identification.  When early data is used with an external PSK, the random value in the ClientHello is the only source of entropy that contributes to key diversity between sessions.  As a result, when an external PSK is used more than one time, the random number source on the client has a significant role in the protection of the early data. </ins> 9. This document makes no IANA requests.


identity collision occurs, the application's external PSK usage will typically take precedence over the internal session resumption path.  7. PSK privacy properties are orthogonal to security properties

cc NAME
Looks good to me.
So the draft talks about collisions between PSK identities, with some assumptions baked in: external and resumption PSK identities are trivial to keep distinct (it takes a single bit), but the draft assumes that this step is not taken it might be necessary to generate PSK identities without any sort of centralized coordination, which means that you might need to worry about collisions, but that's another unstated assumption That first one is pretty poor.
It seems to me that we need to warn implementers about the situation if external and resumption PSKs are not kept distinct. We could include advice to keep them separate.
I suggest the addition of a paragraph at the end of the Section on "PSK Identity Collisions". Since resumption PSK identity is assigned by the TLS stack implementation, it is RECOMMENDED that these identifiers be assigned in a manner that lets resumption PSKs be distinguished from external PSKs to avoid concerns with collisions altogether.

identity collision occurs, the application's external PSK usage will typically take precedence over the internal session resumption path. <ins> Since resumption PSK identities are assigned by the TLS stack implementation, it is RECOMMENDED that these identifiers be assigned in a manner that lets resumption PSKs be distinguished from external PSKs to avoid concerns with collisions altogether. </ins> 7. PSK privacy properties are orthogonal to security properties


FEC describes the sending of redundant information in an outgoing packet stream so that information can still be recovered even in the <del> face of packet loss.  There are multiple ways in which this can be accomplished; this section enumerates the various mechanisms and describes their tradeoffs. </del>  3.1. This approach, as described in RFC5956, Section 4.3, sends FEC <del> packets as an independent SSRC-multiplexed stream, with its own SSRC and payload type.  While this approach can protect multiple packets of the primary encoding with a single FEC packet, each FEC packet will have its own IP+UDP+RTP+FEC header, and this overhead can be excessive in some cases, e.g., when protecting each primary packet with a FEC packet. </del>  This approach allows for recovery of entire RTP packets, including the full RTP header. 3.2. <del> This approach, as descibed in RFC2198, allows for redundant data to </del>  be piggybacked on an existing primary encoding, all in a single packet.  This redundant data may be an exact copy of a previous packet, or for codecs that support variable-bitrate encodings, For AMR/AMR-WB, packets can contain copies or lower-quality encodings of multiple prior audio frames.  This mechanism is similar to the <del> RFC2198 mechanism described above, but as it adds no additional framing, it can be slightly more efficient.  See RFC4867, </del>  Section 3.7.1 for details on this mechanism. In-band FEC mechanisms cannot recover any of the RTP header. 4.1. <del> When using variable-bitrate codecs without an internal FEC, RFC2198 redundant encoding with lower-fidelity version(s) of the previous packet(s) is RECOMMENDED.  This provides reasonable protection of the payload with only moderate bitrate increase, as the redundant encodings can be significantly smaller than the primary encoding. </del>  When using the Opus codec, use of the built-in Opus FEC mechanism is RECOMMENDED.  This provides reasonable protection of the audio stream against individual losses, with minimal overhead.  Note that, as indicated above, the built-in Opus FEC only provides single-frame redundancy; if multi-packet protection is needed, the aforementioned <del> RFC2198 redundancy with reduced-bitrate Opus encodings SHOULD be used </del>  instead. When using the AMR/AMR-WB codecs, use of their built-in FEC mechanism is RECOMMENDED.  This provides slightly more efficient protection of <del> the audio stream than RFC2198. </del>  <del> When using constant-bitrate codecs, e.g.  PCMU, use of RFC2198 redundant encoding MAY be used, but note that this will result in a potentially significant bitrate increase, and that suddenly increasing bitrate to deal with losses from congestion may actually make things worse. </del>  Because of the lower packet rate of audio encodings, usually a single packet per frame, use of a separate FEC stream comes with a higher

While reading the document, I wrote down the following notes that the editor may take into account when revising the document: in 3.1, expland SSRC on first usage and say that this is about sending streams over RTP somewhere early on (I assume this is implied by using the term WebRTC but for outsiders like me it may help to be more specific). Acknowledged. stylistic: I am not a big fan of using citations like '[RFC2198]' as ordinary words or nouns, it makes text difficult to follow unless you know the RFC numbers by heart and your brain translates them back to something meaningful on the fly. This makes texts more difficult to read for outsiders. Example: This mechanism is similar to the [RFC2198] mechanism described above. I prefer this: This mechanism is similar to the redundant encoding mechanism described above. There are couple of such usages of [RFCXXXX] in the document OK. add reference for PCMU OK. Reminder to self, RFC 5391.

FEC describes the sending of redundant information in an outgoing packet stream so that information can still be recovered even in the  <ins> face of packet loss.  There are multiple ways this can be accomplished for RTP media streams RFC3550; this section enumerates the various mechanisms available and describes their tradeoffs. </ins> 3.1. This approach, as described in RFC5956, Section 4.3, sends FEC  <ins> packets as an independent RTP stream with its own synchronization source (SSRC, RFC3550) and payload type, multiplexed with the primary encoding.  While this approach can protect multiple packets of the primary encoding with a single FEC packet, each FEC packet will have its own IP+UDP+RTP+FEC header, and this overhead can be excessive in some cases, e.g., when protecting each primary packet with a FEC packet. </ins> This approach allows for recovery of entire RTP packets, including the full RTP header. 3.2.  <ins> This approach, as described in RFC2198, allows for redundant data to </ins> be piggybacked on an existing primary encoding, all in a single packet.  This redundant data may be an exact copy of a previous packet, or for codecs that support variable-bitrate encodings, For AMR/AMR-WB, packets can contain copies or lower-quality encodings of multiple prior audio frames.  This mechanism is similar to the  <ins> redundant encoding mechanism described above, but as it adds no additional framing, it can be slightly more efficient.  See RFC4867, </ins> Section 3.7.1 for details on this mechanism. In-band FEC mechanisms cannot recover any of the RTP header. 4.1.  <ins> When using variable-bitrate codecs without an internal FEC, redundant encoding (as described in redundant-encoding) with lower-fidelity version(s) of the previous packet(s) is RECOMMENDED.  This provides reasonable protection of the payload with only moderate bitrate increase, as the redundant encodings can be significantly smaller than the primary encoding. </ins> When using the Opus codec, use of the built-in Opus FEC mechanism is RECOMMENDED.  This provides reasonable protection of the audio stream against individual losses, with minimal overhead.  Note that, as indicated above, the built-in Opus FEC only provides single-frame redundancy; if multi-packet protection is needed, the aforementioned  <ins> redundant encoding with reduced-bitrate Opus encodings SHOULD be used </ins> instead. When using the AMR/AMR-WB codecs, use of their built-in FEC mechanism is RECOMMENDED.  This provides slightly more efficient protection of  <ins> the audio stream than redundant encoding. </ins>  <ins> When using constant-bitrate codecs, e.g., PCMU RFC5391, redundant encoding MAY be used, but this will result in a potentially significant bitrate increase, and suddenly increasing bitrate to deal with losses from congestion may actually make things worse. </ins> Because of the lower packet rate of audio encodings, usually a single packet per frame, use of a separate FEC stream comes with a higher


Note that this mechanism can only carry redundancy information for the immediately preceding audio frame; as such the decoder cannot fully recover multiple consecutive lost packets, which can be a <del> problem on wireless networks.  See RFC6716, Section 2.1.7 for complete details. </del>  For AMR/AMR-WB, packets can contain copies or lower-quality encodings of multiple prior audio frames.  See RFC4867, Section 3.7.1 for

I believe this came from a WG mailing list post (possibly my own), rather than an external document that could be linked to. Suggestions? Unfortunately, that was the best RFC reference I could find.

Note that this mechanism can only carry redundancy information for the immediately preceding audio frame; as such the decoder cannot fully recover multiple consecutive lost packets, which can be a  <ins> problem on wireless networks.  See RFC6716, Section 2.1.7, and OpusFEC for more details. </ins> For AMR/AMR-WB, packets can contain copies or lower-quality encodings of multiple prior audio frames.  See RFC4867, Section 3.7.1 for


[[ See issue #105 [78] ]] <del> When used to bind to an access token, the </del>  8.1.

This fixes up a dangling statement from the design team draft that somehow never got completed. It's technically a new normative statement but it was clearly intended by the context so this is not a functional or substantive change. Other changes are small formatting issues.

[[ See issue #105 [78] ]]  <ins> When used to bind to an access token, the access token MUST be covered by the signature method. </ins> 8.1.


the request. The process by which the delegation happens is known as a grant, and <del> the GNAP protocol allows for the negotiation of the grant process over time by multiple parties acting in distinct roles. </del>  This protocol solves many of the same use cases as OAuth 2.0 RFC6749, OpenID Connect OIDC, and the family of protocols that have grown up 1.2. <del> The parties in the GNAP protocol perform actions under different roles.  Roles are defined by the actions taken and the expectations leveraged on the role by the overall protocol. </del>  Manages the requested delegations for the RO.  The AS issues tokens and directly delegated information to the RC.  The AS is Operates and interacts with the RC. <del> The GNAP protocol design does not assume any one deployment architecture, but instead attempts to define roles that can be fulfilled in a number of different ways for different use cases.  As long as a given role fulfills all of its obligations and behaviors as defined by the protocol, GNAP does not make additional requirements on its structure or setup. </del>  Multiple roles can be fulfilled by the same party, and a given party can switch roles in different instances of the protocol.  For 1.4. <del> The GNAP protocol can be used in a variety of ways to allow the core delegation process to take place.  Many portions of this process are </del>  conditionally present depending on the context of the deployments, and not every step in this overview will happen in all circumstances. access of the RS and no longer needs the token. The following sections and examples contain specific guidance on how <del> to use the GNAP protocol in different situations and deployments. </del>  1.4.1. ensure that nothing has been tampered with or substituted in a way that would change the nature of the request. <del> When used in the GNAP delegation protocol, these key binding mechanisms allow the AS to ensure that the keys presented by the RC in the initial request are in control of the party calling any follow-up or continuation requests.  To facilitate this requirement, all keys in the initial request request-key MUST be proved in all continuation requests continue-request and token management requests token-management, modulo any rotations on those keys over time that the AS knows about.  The AS MUST validate all keys request-key or referenced in an ongoing request for each call within that request. </del>  [[ See issue #105 [78] ]]

I attempted to rephrase all occurrences of the redundant "GNAP protocol" in a way that made sense. Most of the time it was changing "the GNAP protocol" to just "GNAP", but there are a few cases where it sounded weird and required some more context.

the request. The process by which the delegation happens is known as a grant, and  <ins> GNAP allows for the negotiation of the grant process over time by multiple parties acting in distinct roles. </ins> This protocol solves many of the same use cases as OAuth 2.0 RFC6749, OpenID Connect OIDC, and the family of protocols that have grown up 1.2.  <ins> The parties in GNAP perform actions under different roles.  Roles are defined by the actions taken and the expectations leveraged on the role by the overall protocol. </ins> Manages the requested delegations for the RO.  The AS issues tokens and directly delegated information to the RC.  The AS is Operates and interacts with the RC.  <ins> The design of GNAP does not assume any one deployment architecture, but instead attempts to define roles that can be fulfilled in a number of different ways for different use cases.  As long as a given role fulfills all of its obligations and behaviors as defined by the protocol, GNAP does not make additional requirements on its structure or setup. </ins> Multiple roles can be fulfilled by the same party, and a given party can switch roles in different instances of the protocol.  For 1.4.  <ins> GNAP can be used in a variety of ways to allow the core delegation process to take place.  Many portions of this process are </ins> conditionally present depending on the context of the deployments, and not every step in this overview will happen in all circumstances. access of the RS and no longer needs the token. The following sections and examples contain specific guidance on how  <ins> to use GNAP in different situations and deployments. </ins> 1.4.1. ensure that nothing has been tampered with or substituted in a way that would change the nature of the request.  <ins> When used for delegation in GNAP, these key binding mechanisms allow the AS to ensure that the keys presented by the RC in the initial request are in control of the party calling any follow-up or continuation requests.  To facilitate this requirement, all keys in the initial request request-key MUST be proved in all continuation requests continue-request and token management requests token- management, modulo any rotations on those keys over time that the AS knows about.  The AS MUST validate all keys request-key or referenced in an ongoing request for each call within that request. </ins> [[ See issue #105 [78] ]]


1. This protocol allows a piece of software, the resource client, to <del> request delegated authorization to resource servers and direct information.  This delegation is facilitated by an authorization server usually on behalf of a resource owner.  The requesting party operating the software may interact with the authorization server to authenticate, provide consent, and authorize the request. </del>  The process by which the delegation happens is known as a grant, and the GNAP protocol allows for the negotiation of the grant process calling an RS, all steps involving the RS below do not apply. In some circumstances, the information needed at a given stage is <del> communicated out-of-band or is pre-configured between the components </del>  or entities performing the roles.  For example, one entity can fulfil multiple roles, and so explicit communication between the roles is not necessary within the protocol flow. oauth-signed-http-request section 4, with the following additional requirements: <del> The at (access token) field MUST be omitted unless this method is being used in conjunction with an access token as in use-access- token.  [[ See issue #112 [86] ]] </del>  <del> The b (body hash) field MUST be calculated and supplied, unless </del>  there is no entity body (such as a GET, OPTIONS, or DELETE request).

iss-sub was renamed to iss_sub in draft -06 of secevent identifiers drop unnecessary hyphenation the initial introduction sentence still might need some more significant rewording

1. This protocol allows a piece of software, the resource client, to  <ins> request delegated authorization to resource servers and to request direct information.  This delegation is facilitated by an authorization server usually on behalf of a resource owner.  The requesting party operating the software may interact with the authorization server to authenticate, provide consent, and authorize the request. </ins> The process by which the delegation happens is known as a grant, and the GNAP protocol allows for the negotiation of the grant process calling an RS, all steps involving the RS below do not apply. In some circumstances, the information needed at a given stage is  <ins> communicated out of band or is preconfigured between the components </ins> or entities performing the roles.  For example, one entity can fulfil multiple roles, and so explicit communication between the roles is not necessary within the protocol flow. oauth-signed-http-request section 4, with the following additional requirements:  <ins> The "at" (access token) field MUST be omitted unless this method is being used in conjunction with an access token as in use- access-token.  [[ See issue #112 [86] ]] </ins>  <ins> The "b" (body hash) field MUST be calculated and supplied, unless </ins> there is no entity body (such as a GET, OPTIONS, or DELETE request).


the HTTP entity body.  Each possible field is detailed in the sections below <del> Indicates that the RC can continue the request by making an additional request using these parameters. </del>  A single access token that the RC can use to call the RS on behalf of the RO. RECOMMENDED.  The amount of time in integer seconds the RC SHOULD wait after receiving this continuation handle and calling the URI. <del> RECOMMENDED.  A unique access token for continuing the request, in </del>  the format specified in response-token-single.  This access token MUST be bound to the RC's key used in the request and MUST NOT be <del> a "bearer" token.  This access token MUST NOT be usable at resources outside of the AS.  If the AS includes an access token, the RC MUST present the access token in all requests to the continuation URI as described in use-access-token.  [[ See issue #66 [35] ]] </del>  The RC can use the values of this field to continue the request as described in continue-request.  Note that the RC MUST sign all <del> continuation requests with its key as described in binding-keys.  If the AS includes an "access_token", the RC MUST present the access token in its continuation request. </del>  This field SHOULD be returned when interaction is expected, to allow the RC to follow up after interaction has been concluded. used to allow the AS and RC to continue negotiating the parameters of the request. <del> To enable this ongoing negotiation, the AS returns a "continue" field response-continue that contains information the RC needs to continue this process with another request, including a URI to access as well as an optional access token to use during the continued requests. </del>  <del> When the RC makes any calls to the continuation URL, the RC MUST present proof of the most recent key associated with this ongoing request by signing the request as described in binding-keys.  The key in use will be either the key from request-key or its most recent rotation.  [[ See issue #85 [58] ]] </del>  <del> For example, here the RC makes a POST request and signs with detached JWS: </del>  <del> If the AS includes an "access_token" in the "continue" response in response-continue, the RC MUST include the access token the request as described in use-access-token.  Note that the access token is always bound to the RC's presented key (or its most recent rotation). For example, here the RC makes a POST request with the interaction reference, includes the access token, and signs with detached JWS: </del>  The AS MUST be able to tell from the RC's request which specific <del> ongoing request is being accessed.  Common methods for doing so include using a unique, unguessable URL for each continuation response, associating the request with the provided access token, or allowing only a single ongoing grant request for a given RC instance at a time.  If the AS cannot determine a single active grant request to map the continuation request to, the AS MUST return an error. </del>  The ability to continue an already-started request allows the RC to perform several important functions, including presenting additional information from interaction, modifying the initial request, and getting the current state of the request.  If a "wait" parameter was included in the response-continue, the RC MUST NOT call the continuation URI prior to waiting the number of seconds indicated.  If no "wait" period is indicated, the RC SHOULD sections below. If the AS determines that the RC can make a further continuation <del> request, the AS MUST include a new response-continue.  If the continuation was previously bound to an access token, the new </del>  "continue" response MUST include a bound access token as well, and <del> this token SHOULD be a new access token.  If the AS does not return a new "continue" response, the RC MUST NOT make an additional continuation request.  If a RC does so, the AS MUST return an error. [[ See issue #87 [60] ]] </del>  For continuation functions that require the RC to send a message body, the body MUST be a JSON object. references: Access is granted by the RO, and a token is issued by the AS.  In its <del> final response, the AS includes a "continue" field: </del>  <del> This allows the RC to make an eventual continuation call.  The RC realizes that it no longer needs "write" access and therefore modifies its ongoing request, here asking for just "read" access instead of both "read" and "write" as before. </del>  The AS replaces the previous "resources" from the first request, allowing the AS to determine if any previously-granted consent When used for delegation in GNAP, these key binding mechanisms allow the AS to ensure that the keys presented by the RC in the initial request are in control of the party calling any follow-up or <del> continuation requests.  To facilitate this requirement, all keys in the initial request request-key MUST be proved in all continuation requests continue-request and token management requests token- management, modulo any rotations on those keys over time that the AS knows about.  The AS MUST validate all keys request-key or referenced in an ongoing request for each call within that request. </del>  [[ See issue #105 [78] ]]

This seems to follow the consensus of the working group as discussed at the meeting and on the list, changes will be merged unless there is a clear alternative proposal accepted by the working group.
How was NAME comment about choosing just one method to keep it simple? Why do we need an access token and a URL?
NAME not sure i understand your question
The AS is choosing how to identify a request by a unique URL, an access token, or having only request at a time from a client. Lots of implementation choices and opportunities to make mistakes -- and overly complex.
There seemed to be some agreement during the IETF109 call that we indeed had to chose between the 2 alternatives. Now that leaves the question of which alternative to select. Between the 2, the editors have proposed (with explanations) to make access tokens mandatory.
Review access token rotation following previous work on Could race conditions occur if the AS rotates its token? Should it be allowed to rotate? See more discussion at URL
We should discuss the potential race condition upon any token rotation, and have an allowance for accepting the old token during a short interim window to account for this kind of race condition. The rotation request needs to be idempotent: a repeated rotation request needs to return the same information and not do another rotation.
Token rotation is now more thoroughly covered and separated from the grant management lifecycle.
Request Continuation: Editor's note: The AS can use the optional "access_token" as a credential for the client to manage the grant request itself over time. This is in parallel with access token management as well as RS access in general. If the AS uses the access token, the continuation URL can be static, and potentially even the same as the initial request URL. If the AS does not use an access token here, it needs to use unique URLs in its response and bind the client's key to requests to those URLs - or potentially only allow one request per client at a time. The optionality adds a layer of complexity, but the client behavior is deterministic in all possible cases and it re-uses existing functions and structures instead of inventing something special just to talk to the AS. The optional access token represents a design compromise, but the working group can decide to either require the access token on all requests or to remove the access token functionality and require the security of the continuation requests be based on unique URLs.
From yesterday's discussion at IETF109, it seemed we agreed that it would be best to have only one way to do the continuation. I personally would be in favor of having a mandatory access token (not a bearer token, needs to prove key possession), and a simple uri. As NAME remarked, "URL" is effectively an access token in a URL, also known as a capability URL, which the w3c has a whole document about the pros and cons of: URL
NAME No, my proposal to rename to referred to two of the proposals to address , not to the example you are quoting. There we bundle a LOT more into a structure called . Slides 32-33 of the deck.
my bad, makes sense. I crossed the related line in the previous comment, and updated the json. note for the future: if we can avoid going back and forth in the presentation, will avoid such misunderstandings ;-)
Part of the confusion here is that we're talking about changing the format of what's currently in response messages. That construct gets used in both the continuation protocol (here) and in the access tokens for RS's. The parallelism is deliberate, so if we change it in one place it'll change in both. I'm in favor of both requiring the access token for the continuation API and in renaming the structure to , but these are separate issues.
"URL" is an identifier just as "URL" is an identifier It is not a capability URL, as there is NO authentication with capability URLs. In GNAP, the API calls are all authenticated by the client proving possession of its key. Per my email to the list, what we are calling an access token is more like a cookie as it is maintaining state. How it is set, where it can be presented, are unlike other access tokens -- calling it an access token dilutes the meaning of access tokens and is confusing.
It's not a cookie either. The goal is not to maintain state, it's only to execute the next transition (more details on the ) That's the limit of analogies (neither a capability nor a cookie). If I summarize we have the following issues: putting the token directly in the url exposes to potential unexpected url logging from proxies (we don't want that) setting the token aside is the alternative, but the difference with a standard access token (as used by RS) might be confusing to implementers (I agree there is a little risk here). That difference is currently expressed by the "key" boolean parameter, which could easily be overlooked. If we want to stress the difference with an access token used in the context of RS, there are a few options: name it differently altogether (like "continue token"). We'd loose the parallelism that Justin was talking about though (which is nice if we can find a way to avoid the confusion at minor cost) add a "type" within the json of the access token. But then we need to deal with mutual exclusivity with the key field. Not a good idea. change the key field to a name that is more meaningful, like "requireskeyauthentication" or "requireskeypop" (proof of possession). It's longer but I believe it conveys the meaning better, it becomes really hard to miss. With the last option we could have something like
The parameter is not different from the standard access token response, though -- it's a required field for all access tokens, no matter which API they call (whether it's within the AS like the continuation API or an OpenID UserInfo Endpoint, or a separate RS alltogether). URL The only difference here is that the field is currently restricted a specific required value because we want to limit what we expect the client to be able to do when calling the continuation API. The boolean value of signals that the token is bound to the same key the client presented during its initial request. This means that the client needs to continue to present that key along with the access token for the continuation calls. I would argue (as others have) that this ought to be the default for :all: access tokens issued to the client within GNAP. We could relax this restriction, but it would mean that we'd end up with a potentially more complex space for a client to deal with when an AS binds to a different key or proofing mechanism for continuation. Plus, I think we all agree that a bearer token for continuation is a non-starter.
What I meant before is that people might overlook the meaning of "key" and what it implies, so we might need to make it more obvious. If we were to make key verification mandatory, it would remove the issue altogether, improve the security, and I see no potential confusion for the implementer. But it might come as a challenge where bearer tokens are used today (for APIs). Not hard to implement, but any change like that takes time to disseminate within the ecosystem. And there may still be some valid cases for bearer tokens, but indeed continuation is not one of them ;-) A possibility is to make key verification the default (for AS as well as RS), and still be able to handle bearer tokens with a boolean "bearer", by default set to false (but that field wouldn't be valid in the context of the continuation endpoint). Here we would have : and for the resources we might indicate that it is actually a bearer token, only if it is declared explicitly :
This is an interesting approach. I'm in favor of the proposed default behavior of binding to the client's key, but I'm not sure I'm sold on default values when a field is absent, like this. In the current spec, the only way to get a bearer token is to set in the token response. Since is mandatory there is technically no ambiguity about the nature of a token since there's no "default" value if it's not present, it's an error. An older version of the XYZ draft had something similar, with a field alongside a separate field. The problem came from the situation of having a bearer flag alongside a key. That was an error condition that needed to be checked by the client now. With the current draft, that error is impossible at a syntax level, which I think is a benefit for client implementors.
To expand a bit: what I'm saying is that the semantics of key binding need to be very clear for the token. A client implementor should never overlook the value in the current access token structure since it says exactly how the token is bound to outgoing requests.
I agree with that. I think we're on similar lines of thought here. One could argue however that having a true/false flag makes it possible to overlook the field (hence why I suggested that in the case of continuation, it's not even present; or if we want to make it explicit, the only valid json contains "key":true).
We could combine the concepts, and say that if the field is not present, its value is .
Thinking about this for half a second more, I think we need to refactor out the key presentation and its semantics from where it is in the spec right now, since it isn't just about the client presenting a key and it's confusing people:
tbh doesn't tell me much about what that is or why I need it. I'd be in favor of naming it something more specific.
Since we had a lengthy discussion on the rationale for the change, I copy paste it here The access token pattern has a lot of benefits, otherwise we wouldn’t have an entire OAuth ecosystem based on it Magic URIs have a lot of drawbacks which are well understood; while they can be mitigated, they can also be avoided Continuation is an API, and treating it like the other kinds of API the client would call makes sense Calling this by a special name, like “grant access token” or “continuation access token” is fine, but it should function like any other access token The heavy lift for clients is on protecting the message cryptographically, which they need to do anyway From URL
I've looked at the rest (besides Yaron's comments), seems fine to me. The editors and chairs would like to confirm consensus on a current pull request: URL This pull request simplifies the continuation response and request by making the access token mandatory, and it clarifies the responsibilities of the AS in enforcing the security of the continuation request. Several WG members expressed specific support for keeping the access token to enable specific use cases, and there was general support for simplifying the process from what it currently is in the draft. The editors believe the pull request represents a solution that meets these goals. This call is open until Monday December 14. At that point, the PR will be merged unless the chairs determine there is not rough consensus for its inclusion. Thank you, Justin, Aaron, and Fabien
I agree with Fabien that the persistent identifier is a separate issue. The current spec re-uses the access token for this artifact, but that’s potentially brittle and could be changed out for something else. There’s an issue asking for expanding on the use cases for this functionality (which hasn’t been addressed by this PR): URL A potentially-rotating URI would be just as brittle, and so having a single codified identifier for this artifact would be useful, but it does assume some things about the nature of the AS. Every other use the client has to manage the ongoing request over time doesn’t need an explicit identifier. Just like with OAuth-protected APIs, the server can determine the context not just from the URI but from the rest of the request, including the access token itself. This is both more common and more powerful than a strict reading of REST designs. It also follows the HATEOS principles as the entire HTTP request is taken into account, including the access token and signature portions. I’ll also point out that the rotation of these credentials is also filed as a separate issue that’s not being addressed right now, so we can revisit that discussion separately: URL As for the name, we could give it a different label. We have this same pattern of issuing a resource-specific access token alongside a URL in the Dynamic Registration specification, both in OAuth (URL ) and OpenID Connect (URL ). Here it’s called the “registration access token” — but what’s important there, as it is here, is that it’s not a different kind of artifact that the client now has to figure out how to use, it’s an access token plain and simple. In the OAuth world this is a bearer token, since that’s what OAuth 2 uses. In the GNAP world it’ll be a bound token, as that’s what we’re looking to build on. This is also related to another future discussion about responses tying an access token to a specific API that’s told to the client, as we could potentially re-use those components and concepts here as well: URL And finally, no speculation on the complexity is needed: I implemented this pattern several months ago during the design team discussions when we were considering this pattern, and the code is all online for people to see. URL On the AS side, the most interesting code to this discussion is in the TransactionEndpoint class: URL Here, you’ll see that on initial request, the server looks up the client to see if it’s been registered, but after that, it makes sure that the token and key are appropriate for the ongoing request. From the client side it’s even simpler. The client’s got a small service function to manage the different signature methods that are implemented, and all of them can take in an optional access token: URL The heavy lift is doing the actual signing, and you need that in order to start the process anyway. Managing the access token as an artifact to use at the API is completely trivial since the client already needs to manage its own state internally to do any of this. And note that all of this is changed from how it was before: Previously, the XYZ Protocol had used a “transaction handle” returned by the AS that the client would use to continue the request. However, this simple model was limiting, and the design team adopted XAuth’s model of continuation being an API. In doing so, we made it like all of the other APIs the client is going to call: in the initial state, it doesn’t have any kind of access rights, it’s just calling. From that initial call forward, the AS just needs to know that the token and key match what it expects. In summary, my views are: The access token pattern has a lot of benefits, otherwise we wouldn’t have an entire OAuth ecosystem based on it Magic URIs have a lot of drawbacks which are well understood; while they can be mitigated, they can also be avoided Continuation is an API, and treating it like the other kinds of API the client would call makes sense Calling this by a special name, like “grant access token” or “continuation access token” is fine, but it should function like any other access token The heavy lift for clients is on protecting the message cryptographically, which they need to do anyway — Justin
Hi Dick, In GNAP, the client isn't managing state (unlike a web app), the entire point is that the lifecycle should be managed by the AS. As in any state machine, there are states and transitions. Here we're not passing state, merely expressing "please continue". The client can be completely unaware of the underlying state. In effect the client only has the ability to ask the server to generate the next transition. So I don't think you can compare that to cookies. It's a different behavior. BTW if it was the case it would lead to a whole new class of issues, because there's an entire legal framework around cookies... To avoid confusion with a standard access token, we have the "key" field. My proposal would be to make it more explicitly (cf comment in issue 67). Fabien Le lun. 23 nov. 2020 à 02:06, Dick Hardt a écrit : >
So we've established that this is a different access token, that requires different handling at the client. So keeping it could cause more confusion? As an RC, I will have to store the continue as although it could be static it could also be dynamic. Why do I need to store an access token as well. It brings me no benefit as an RC, in fact it brings more complexity. As I will now need to manage multiple types of tokens with different lifecycles: Continuation token can only be used at the continue endpoint (the name of which is confusing as I can use this endpoint to revoke a grant or get metadata on the grant). may be rotated each time it is used, or may not be provided in the section of the response must be sender-constrained can't be used with the token management APIs? can be used to identify the grant when making subsequent grants Access token(s) to use at RS can only be used at the specified RS may be sender constrained when used at the RS, will not result in rotation >From my perspective, most use-cases will require the RC to have a persistent identifier for the grant. Why not bring this into the protocol and let the AS provide this persistent identifier (through the form of the continue uri). Using a rotating access token as a persistent identifier doesn't seem like the right choice. I see no security benefit to having the continuation access token. It doesn't matter if the continue uri leaks as it is useless without an accompanying signature, i.e. any security benefit of having an access token is already provided by having a signature. The only benefits that I can see are: If the AS wants to be fully stateless, then you can encode more data in a token than in a uri If the AS wants to have a static endpoint for CRUD operations on the grant To allow the AS to identity a previous grant If we dropped the access token for the continue endpoint and rather mandated a dynamic uri this would make things conceptually easier to understand, easier for the RC to implement, easier to debug and less chance of errors when rotating tokens (i.e. race conditions could be quite likely if the AS always rotates the token) One-off grant with no continuation or ongoing management: RC sends signature and metadata, no response provided, therefore no grant management possible Grant with ongoing management RC sends signature and metadata, AS responds with a continue uri that has these purposes: can be used by the RC to continue/update, read or revoke the grant can be used by the RC when making a new grant to identify the previous grant As an RC the only permanent items I need to store are: the continue uri associated with the grant any access tokens I receive for the grant Dave On Tue, 15 Dec 2020 at 10:11, Fabien Imbault wrote: Dave Tonge CTO [image: Moneyhub Enterprise] Moneyhub Financial Technology, 5th Floor, 10 Temple Back, Bristol, BS1 6FL t: +44 (0)117 280 5120 Moneyhub Enterprise is a trading style of Moneyhub Financial Technology Limited which is authorised and regulated by the Financial Conduct Authority ("FCA"). Moneyhub Financial Technology is entered on the Financial Services Register (FRN 809360) at URL . Moneyhub Financial Technology is registered in England & Wales, company registration number 06909772 . Moneyhub Financial Technology Limited 2019 DISCLAIMER: This email (including any attachments) is subject to copyright, and the information in it is confidential. Use of this email or of any information in it other than by the addressee is unauthorised and unlawful. Whilst reasonable efforts are made to ensure that any attachments are virus-free, it is the recipient's sole responsibility to scan all attachments for viruses. All calls and emails to and from this company may be monitored and recorded for legitimate purposes relating to this company's business. Any opinions expressed in this email (or in any attachments) are those of the author and do not necessarily represent the opinions of Moneyhub Financial Technology Limited or of any other group company. Moneyhub Enterprise is a trading style of Moneyhub Financial Technology Limited which is authorised and regulated by the Financial Conduct Authority ("FCA"). Moneyhub Financial Technology is entered on the Financial Services Register (FRN 809360) at URL . Moneyhub Financial Technology is registered in England & Wales, company registration number 06909772. Moneyhub Financial Technology Limited 2020 Moneyhub Enterprise, Regus Building, Temple Quay, 1 Friary, Bristol, BS1 6EA. DISCLAIMER: This email (including any attachments) is subject to copyright, and the information in it is confidential. Use of this email or of any information in it other than by the addressee is unauthorised and unlawful. Whilst reasonable efforts are made to ensure that any attachments are virus-free, it is the recipient's sole responsibility to scan all attachments for viruses. All calls and emails to and from this company may be monitored and recorded for legitimate purposes relating to this company's business. Any opinions expressed in this email (or in any attachments) are those of the author and do not necessarily represent the opinions of Moneyhub Financial Technology Limited or of any other group company.

the HTTP entity body.  Each possible field is detailed in the sections below  <ins> Indicates that the RC can continue the request by making one or more continuation requests. </ins> A single access token that the RC can use to call the RS on behalf of the RO. RECOMMENDED.  The amount of time in integer seconds the RC SHOULD wait after receiving this continuation handle and calling the URI.  <ins> REQUIRED.  A unique access token for continuing the request, in </ins> the format specified in response-token-single.  This access token MUST be bound to the RC's key used in the request and MUST NOT be  <ins> a bearer token.  As a consequence, the "key" field of this access token is always the boolean value "true".  This access token MUST NOT be usable at resources outside of the AS.  The RC MUST present the access token in all requests to the continuation URI as described in use-access-token.  [[ See issue #66 [35] ]] </ins> The RC can use the values of this field to continue the request as described in continue-request.  Note that the RC MUST sign all  <ins> continuation requests with its key as described in binding-keys and MUST present the access token in its continuation request. </ins> This field SHOULD be returned when interaction is expected, to allow the RC to follow up after interaction has been concluded. used to allow the AS and RC to continue negotiating the parameters of the request.  <ins> To enable this ongoing negotiation, the AS provides a continuation API to the RC.  The AS returns a "continue" field response-continue that contains information the RC needs to access this API, including a URI to access as well as an access token to use during the continued requests. </ins>  <ins> The access token is initially bound to the same key and method the RC used to make the initial request.  As a consequence, when the RC makes any calls to the continuation URL, the RC MUST present the access token as described in use-access-token and present proof of the RC's key (or its most recent rotation) by signing the request as described in binding-keys. </ins>  <ins> [[ See issue #85 [58] ]] </ins>  <ins> For example, here the RC makes a POST request to a unique URI and signs the request with detached JWS: </ins> The AS MUST be able to tell from the RC's request which specific  <ins> ongoing request is being accessed, using a combination of the continuation URL, the provided access token, and the RC instance identified by the key signature.  If the AS cannot determine a single active grant request to map the continuation request to, the AS MUST return an error. </ins> The ability to continue an already-started request allows the RC to perform several important functions, including presenting additional information from interaction, modifying the initial request, and getting the current state of the request. <ins> All requests to the continuation API are protected by this bound access token.  For example, here the RC makes a POST request to a stable continuation endpoint URL with the continue-after-interaction, includes the access token, and signs with detached JWS: </ins> If a "wait" parameter was included in the response-continue, the RC MUST NOT call the continuation URI prior to waiting the number of seconds indicated.  If no "wait" period is indicated, the RC SHOULD sections below. If the AS determines that the RC can make a further continuation  <ins> request, the AS MUST include a new response-continue.  The new </ins> "continue" response MUST include a bound access token as well, and  <ins> this token SHOULD be a new access token, invalidating the previous access token.  If the AS does not return a new "continue" response, the RC MUST NOT make an additional continuation request.  If a RC does so, the AS MUST return an error.  [[ See issue #87 [60] ]] </ins> For continuation functions that require the RC to send a message body, the body MUST be a JSON object. references: Access is granted by the RO, and a token is issued by the AS.  In its  <ins> final response, the AS includes a "continue" field, which includes a separate access token for accessing the continuation API: </ins>  <ins> This "continue" field allows the RC to make an eventual continuation call.  In the future, the RC realizes that it no longer needs "write" access and therefore modifies its ongoing request, here asking for just "read" access instead of both "read" and "write" as before. </ins> The AS replaces the previous "resources" from the first request, allowing the AS to determine if any previously-granted consent When used for delegation in GNAP, these key binding mechanisms allow the AS to ensure that the keys presented by the RC in the initial request are in control of the party calling any follow-up or  <ins> continuation requests.  To facilitate this requirement, the response- continue includes an access token bound to the request-key, and that key (or its most recent rotation) MUST be proved in all continuation requests continue-request.  Token management requests token- management are similarly bound to either the access token's own key or, in the case of bearer tokens, the RC's key.  The AS MUST validate all keys request-key or referenced in an ongoing request for each call within that request. </ins> [[ See issue #105 [78] ]]


makes an HTTP DELETE request to the continuation URI. If the request is successfully cancelled, the AS responds with an <del> HTTP 202.  The AS MUST revoke all associated access tokens, if possible. </del>  6.

I don't know much about the GNAP revocation plan, but it seems like having text specifying 'MUST if possible' is the same as SHOULD, per RFC 2119. Maybe I'm missing something :) I read the contributing doc, but if PRs as contributions aren't acceptable, please let me know.
PR text contributions are just fine, they fall under the IETF contribution guidelines. Thank you! See and for discussion on token revocation.
Thanks, those both deal with token rotation; not sure if that is different than token revocation/cancelling. It seems like the "MUST invalidate the current access token ... if possible" is used in a few different places. I see it in 5.5, 6.1, 6.2. I guess I don't understand what "MUST ... if possible" means from an implementation standpoint, other than "SHOULD". (If this has been discussed on the mailing list--a quick search there didn't turn anything up.
The issues in question are specifically about what to do with old tokens under rotation circumstances, which falls under the same conversation as what to do with explicitly revoked tokens that's addressed here. I linked those issues because the same discussion of "if possible" has been brought up in those places as well (as you point out here). Before a PR like this is accepted with a normative change, we need to bring the proposal to the working group for consensus building. If you want to kick off the conversation on the list more quickly, please feel free to start a thread and link to this PR! Why the "MUST if possible" phrasing? Mostly because sometimes it's impossible to revoke a token once it's in flight. Some OAuth 2 systems today use self-contained access tokens, which by nature can't be revoked in any meaningful way. However, the requirement is that if the AS is able to revoke the tokens, then it doesn't have a choice in doing so. If it's impossible for the AS to fulfill the requirement, that's ok, but the AS doesn't get to just choose to not revoke the tokens, it just can't. To me this seems more than a SHOULD, but I could be wrong.
As currently written, this does read like a SHOULD. If we care a lot about token revocation, we can make it a MUST and totally disallow self-contained tokens. If we don't, we need to clarify the situation, maybe by defining revocable vs. non-revocable tokens. And then say that in this instance, if the tokens are revocable, they MUST be revoked.
That was the intent of the text as it is right now. I kinda like the idea of "revocability" being a variable attribute on access tokens, as it allows us to talk about them in different ways. There's currently a stub section in the document (appendix B) for talking about the data models, and this would be part of that discussion.
The idea of specifying whether tokens are revocable or not might be useful. We might want to illustrate when we'd use one vs the other. One could imagine using non revocable tokens when the information is not critical, short lived and when maintaining state is not worth the trouble. Note that there's the potential issue of allowing rotating these tokens, while not revoking them, hereby creating new tokens without falling into the classic flow. So probably we should limit that behavior. Revocable tokens would require that current tokens be revoked (MUST) when they're rotated.
Rotating the Access Token: Editor's note: We could also use different verbs to signal whether or not the old token should be kept around or not, instead of using a token flag to do this.
Keep "MUST if possible" here. If you want two access tokens, use the grant API not the token rotation API. The rotation mechanism should be for getting a new value for an existing token and replacing it, not for minting entirely new separate tokens (which is what the grant continuation/update API is for). We need to keep "if possible" for the case of using stateless tokens (fully self-contained JWTs), and add a discussion on when it might not be possible.
Modifying an Existing Request: Editor's note: This might be subject to the "multi_token" flag, but since we're creating a NEW access token and not rotating an existing one, this seems to be a different use case. There is a solid argument to be made for always revoking old access tokens here, but we need more discussion on the boundaries for such a requirement. If they stick around, it does make a "read" request weird because now we've got multiple access tokens sticking around associated with a grant request and no good place to put them.
I don't think we should put a strict requirement on revoking old access tokens, since it may be difficult or impossible in some implementations. At most this could be a "SHOULD" or "RECOMMENDED".

makes an HTTP DELETE request to the continuation URI. If the request is successfully cancelled, the AS responds with an  <ins> HTTP 202.  The AS SHOULD revoke all associated access tokens. </ins> 6.


those privileges to an end-user.  This process is refered to as privilege delegation. <del> protected API (Application Programming Interface) served by a RS </del>  and that can be accessed by a client, if and only if a valid access token is provided.  Note: to avoid complex sentences, the specification document may simply refer to resource instead of protected resource. ability given to a subject to perform a given operation on a <del> resource under the control of a RS. </del>  person, organization or device. parameters for the incoming request match those that it is expecting from the session created in (1).  The client instance also needs to be prepared for the end-user never being returned to <del> the client instance and handle time outs appropriately. </del>  The client instance loads the continuation information from (3) and sends the interaction reference from (7) in a request to Claims about the RO as known and declared by the AS. <del> An identifier this client instance instance can use to identify itself when making future requests. </del>  <del> An identifier this client instance instance can use to identify its current end-user when making future requests. </del>  An error code indicating that something has gone wrong.

Deploy preview for gnap-core-protocol-editors-draft ready! Built with commit fd1d0f88ac7d2a9ad6f43bb6d959a2aa84558f2b https://deploy-preview-179--gnap-core-protocol-editors-URL
One small change needed (marked) but otherwise good!

those privileges to an end-user.  This process is refered to as privilege delegation.  <ins> protected API (Application Programming Interface) served by an RS </ins> and that can be accessed by a client, if and only if a valid access token is provided.  Note: to avoid complex sentences, the specification document may simply refer to resource instead of protected resource. ability given to a subject to perform a given operation on a  <ins> resource under the control of an RS. </ins> person, organization or device. parameters for the incoming request match those that it is expecting from the session created in (1).  The client instance also needs to be prepared for the end-user never being returned to  <ins> the client instance and handle timeouts appropriately. </ins> The client instance loads the continuation information from (3) and sends the interaction reference from (7) in a request to Claims about the RO as known and declared by the AS.  <ins> An identifier this client instance can use to identify itself when making future requests. </ins>  <ins> An identifier this client instance can use to identify its current end-user when making future requests. </ins> An error code indicating that something has gone wrong.


endpoint to retrieve the server's discovery information.  The AS MUST respond with a JSON document containing the following information: <del> REQUIRED.  The full URL of the AS's grant request endpoint.  This MUST match the URL the client instance used to make the discovery request. </del>  OPTIONAL.  A list of the AS's capabilities.  The values of this result MAY be used by the client instance in the request-

Suggested changes for URL They could be also simplified to something like
Deploy preview for gnap-core-protocol-editors-draft ready! Built with commit 0569eb3db265511e06d7fb19b2320081d4626430 https://deploy-preview-183--gnap-core-protocol-editors-URL
Sections "9 Discovery" states that It makes sense to specify that this URL should be using HTTPS. I also don't think you want to allow using the fragment component in it, as well as query parameters. The query parameters could be arguable though...
This definition should be beyond just the discovery portion -- this endpoint is fundamental to the protocol and it does need to be protected. We can at least mention that it starts with HTTPS here. Prohibiting fragments makes sense, but prohibiting query parameters or any other URL portion does not make sense, though, as that could be important to an AS's deployment. However, the client instance always takes this string as-is and doesn't add or modify anything, and it always makes a POST to it.
URL
I've reused the definition of . That is a very precise one IMO.

endpoint to retrieve the server's discovery information.  The AS MUST respond with a JSON document containing the following information:  <ins> REQUIRED.  The location of the AS's grant request endpoint.  The location MUST be a URL RFC3986 with a scheme component that MUST be https, a host component, and optionally, port, path and query components and no fragment components.  This URL MUST match the URL the client instance used to make the discovery request. </ins> OPTIONAL.  A list of the AS's capabilities.  The values of this result MAY be used by the client instance in the request-


A timestamp of the request in integer seconds <del> When to bind a request to an access token, the access token hash </del>  value.  Its value is the base64url encoding of the left-most half of the hash of the octets of the ASCII representation of the "access_token" value, where the hash algorithm used is the hash This method is indicated by "dpop" in the "proof" field.  The client instance creates a Demonstration of Proof-of-Possession signature <del> header as described in I-D.ietf-oauth-dpop section 2.  In addition to the required fields, the DPoP body MUST also contain a digest of the request body: </del>  Digest of the request body as the value of the Digest header <del> defined in RFC3230. </del>  7.3.5.

Changes field to , adds to DPoP definition for parity with other JOSE signature methods.
Deploy preview for gnap-core-protocol-editors-draft ready! Built with commit fc15fc873432dae90bce38706aa85313d831d419 https://deploy-preview-195--gnap-core-protocol-editors-URL
The signature methods all need to cover the access token, but the DPoP method currently does not. We can add the method used in the and methods.
The FAPI WG is proposing a similar DPoP profile: URL This uses the field instead of , and we could align with that.
Convergence would be helpful, do we know the status of the document?
Is this something that can be standardized in , even as a best practice or recommendation? Trying to align with all documents out there is not a long time strategy...
I've reached out to the OAuth WG on the topic of defining the field in DPoP itself. If that happens we can remove this field from our spec, but until that happens then it makes sense to keep FAPI and GNAP aligned, for now.
Regarding alignment between FAPI and GNAP... DPoP describes "htu" as while GNAP as which obviously isn't the same.

A timestamp of the request in integer seconds  <ins> When a request is bound to an access token, the access token hash </ins> value.  Its value is the base64url encoding of the left-most half of the hash of the octets of the ASCII representation of the "access_token" value, where the hash algorithm used is the hash This method is indicated by "dpop" in the "proof" field.  The client instance creates a Demonstration of Proof-of-Possession signature  <ins> header as described in I-D.ietf-oauth-dpop section 2.  In addition, this specification defines the following fields to be added to the DPoP payload: </ins> Digest of the request body as the value of the Digest header  <ins> defined in RFC3230.  When a request contains a message body, such as a POST or PUT request, this field is REQUIRED. When a request is bound to an access token, the access token hash value.  Its value is the base64url encoding of the left-most half of the hash of the octets of the ASCII representation of the "access_token" value, where the hash algorithm used is the hash algorithm used in the "alg" header parameter of the JWS's JOSE Header.  For instance, if the "alg" is "RS256", hash the "access_token" value with SHA-256, then take the left-most 128 bits and base64url encode them. </ins> 7.3.5.


A non-normative example of a grant request is below: <del> The request MUST be sent as a JSON object in the body of the HTTP POST request with Content-Type "application/json", unless otherwise specified by the signature mechanism. </del>  2.1.

The specification doesn't mention the Cache-Control header, as well as the Content-Type header for the responses. This is the 1st step to add this information. All examples of responses may also include this header. Right now, it's true for a few examples. I am unsure if it's necessary to include a bit obsolete header Pragma. URL
Deploy preview for gnap-core-protocol-editors-draft ready! Built with commit 8a756ce36a5af1b0f97c6abc17ab1d772adfde10 https://deploy-preview-199--gnap-core-protocol-editors-URL
This seems like it's still in progress, so I've marked it as a draft for now. Would like to see more input on the right behavior around cache control headers here.
There is no place for the Pragma header. This header is actually for a request, not a response, and it’s for backward compatibility for ancient HTTP 1.0. explains what this header does. There was even about the improper use of this header. The draft for OAuth 2.1 (which is currently under development) still suggests using it. Although, I don’t really think it does it for some particular purpose other than historical reasons. I believe "Cache-Control: no-store” will be sufficient.
NAME do you still want me to provide more inputs on this one?
Roles: Editor's note: The names for the roles are an area of ongoing discussion within the working group, as is the appropriate precision of what activities and expectations a particular role covers. In particular, the AS might be formally decomposed into delegation components, that the client talks to, and interaction components, that the user talks to. Several alternative names have been proposed for different roles and components, including: Grant Server (for Authorization Server) Grant Client (for Resource Client) Operator (for Requesting Party) See also
Part of the terminology
Process comment: I suggest to move the top note over to and close this one as Duplicate.
Closing as duplicate Examples in RFC 6750 and RFC 6749 as well as some normative text in section of RFC 6749 use a "Pragma: no-cache" HTTP response header. However, both RFC 2616 and the shiny new RFC 7234 make special note along the lines of the following to say that it doesn't work as response header: 'Note: Because the meaning of "Pragma: no-cache" in responses is not specified, it does not provide a reliable replacement for "Cache-Control: no-cache" in them.' The header doesn't hurt anything, I don't think, so having it in these documents isn't really a problem. But it seems like it'd be better to not further perpetuate the "Pragma: no-cache" response header myth in actual published RFCs. So with that said, two questions: 1) Do folks agree that 6747/6750 are using the "Pragma: no-cache" response header inappropriately? 2) If so, does this qualify as errata?

A non-normative example of a grant request is below:  <ins> The request and response MUST be sent as a JSON object in the body of the HTTP POST request with Content-Type "application/json", unless otherwise specified by the signature mechanism. The authorization server MUST include the HTTP "Cache-Control" response header field RFC7234 with a value set to "no-store". </ins> 2.1.


described in response-token-single. When neither an access token nor key proof are used, this is an <del> unsecured request.  This type of used only for calls to the RS during a discovery phase as described in rs-request-without-token. </del>  7.1. general-purpose APIs use a URI for this field to avoid collisions between multiple API types protected by a single AS. <del> While it is expected that many APIs will have its own properties, a </del>  set of common properties are defined here.  Specific API implementations SHOULD NOT re-use these fields with different semantics or syntax.  The available values for these properties are The access requested for a given object when using these fields is the cross-product of all fields of the object.  That is to say, the object represents a request for all "action" values listed within the <del> object to be used at all "locations" values listed within the object </del>  for all "datatype" values listed within the object.  Assuming the request above was granted, the client instance could assume that it would be able to do a "read" action against the "images" on the first

Minor typos
Deploy preview for gnap-core-protocol-editors-draft ready! Built with commit b2ce64bfa924bc30b24ea9301223156ec0eb8520 https://deploy-preview-204--gnap-core-protocol-editors-URL
within (and likely other sections), the property names are plural, but the text sometimes refers to the singular property names. This should be cleaned up to be consistent one way or another.

described in response-token-single. When neither an access token nor key proof are used, this is an  <ins> unsecured request.  This type of request is used only for calls to the RS during a discovery phase as described in rs-request- without-token. </ins> 7.1. general-purpose APIs use a URI for this field to avoid collisions between multiple API types protected by a single AS.  <ins> While it is expected that many APIs will have their own properties, a </ins> set of common properties are defined here.  Specific API implementations SHOULD NOT re-use these fields with different semantics or syntax.  The available values for these properties are The access requested for a given object when using these fields is the cross-product of all fields of the object.  That is to say, the object represents a request for all "action" values listed within the  <ins> object to be used at all "location" values listed within the object </ins> for all "datatype" values listed within the object.  Assuming the request above was granted, the client instance could assume that it would be able to do a "read" action against the "images" on the first


7.3.1. This method is indicated by "jwsd" in the "proof" field.  A JWS <del> RFC7515 signature object is created as follows: </del>  <del> The header of the JWS MUST contain the "kid" field of the key bound to this client instance for this request.  The JWS header MUST contain an "alg" field appropriate for the key identified by kid and MUST NOT be "none".  The "b64" field MUST be set to "false" and the "crit" field MUST contain at least "b64" as specified in </del>  <del> To protect the request, the JWS header MUST contain the following additional fields. </del>  The HTTP Method used to make this request, as an uppercase ASCII string. 7.3.2. This method is indicated by "jws" in the "proof" field.  A JWS <del> RFC7515 signature object is created as follows: </del>  <del> The header of the JWS MUST contain the "kid" field of the key bound to this client instance for this request.  The JWS header MUST contain an "alg" field appropriate for the key identified by "kid" and MUST NOT be "none". </del>  To protect the request, the JWS header MUST contain the following <del> additional fields. </del>  The HTTP Method used to make this request, as an uppercase ASCII string.

These changes replace with replace with replace with in Detached JWS and Attached JWS sections.
Deploy preview for gnap-core-protocol-editors-draft ready! Built with commit df67d81f6aadce526a2eecb1d9185d684f17242c https://deploy-preview-207--gnap-core-protocol-editors-URL
I think the proposal in could have some impact on this language, as well as making sure both attached and detached JWS methods are fully aligned.
could definitely have some impact. Although, these changes touch only the used terminology.
Accept to align with JOSE terminology, will probably be updated again when crypto methods get updated.

7.3.1. This method is indicated by "jwsd" in the "proof" field.  A JWS  <ins> RFC7515 object is created as follows: </ins>  <ins> The JOSE (JSON Object Signing and Encryption) header MUST contain the "kid" parameter of the key bound to this client instance for this request.  The "alg" parameter MUST be set to a value appropriate for the key identified by kid and MUST NOT be "none".  The "b64" parameter MUST be set to "false" and the "crit" parameter MUST contain at least "b64" as specified in RFC7797. </ins>  <ins> To protect the request, the JOSE header MUST contain the following additional parameters. </ins> The HTTP Method used to make this request, as an uppercase ASCII string. 7.3.2. This method is indicated by "jws" in the "proof" field.  A JWS  <ins> RFC7515 object is created as follows: </ins>  <ins> The JOSE header MUST contain the "kid" parameter of the key bound to this client instance for this request.  The "alg" parameter MUST be set to a value appropriate for the key identified by kid and MUST NOT be "none". </ins> To protect the request, the JWS header MUST contain the following  <ins> additional parameters. </ins> The HTTP Method used to make this request, as an uppercase ASCII string.