An application server can voluntarily identify itself to a push service using the described technique.  This identification information can be used by the push service to attribute requests <del> that are made by the same application server to a single entity, and reduce the need for endpoint secrecy by being able to associate subscriptions with an application server.  An application server is further able include additional information the operator of a push service can use to contact the operator of the application server. </del>  1. exposed to a greater risk of denial of service attack.  While requests from application servers can be indirectly attributed to user agents, this is not always efficient or even sufficient. <del> Providing more information about the application server more directly to a push service allows the push service to better distinguish between legitimate and bogus requests. </del>  Additionally, this design also relies on endpoint secrecy as any application server in possession of the endpoint is able to send messages, albeit without payloads.  In situations where usage of a subscription can be limited to a single application server, the <del> ability to associate said subscription with the application server provides could reduce the impact of a data leak. </del>  This document describes a system whereby an application server can volunteer information about itself to a push service.  At a minimum, preference over an unidentified application server when choosing whether to discard a push message. <del> 1.1. </del>  The words "MUST", "MUST NOT", "SHOULD", and "MAY" are used in this document.  It's not shouting, when they are capitalized, they have the special meaning described in RFC2119. <del> The terms "push message", "push service", "application server", and "user agent" are used as defined in </del>  2. <del> Several options have been proposed, here are some of the more concrete options. </del>  2.1. <del> A push service that supports application server self-identification requests a client certificate from application servers.  The client certificate is requested during the TLS RFC5246 handshake. An application server that does not have a client certificate offers no certificate in response; an application server that wishes to self-identify includes a certificate. The certificate that the application server offers SHOULD be self- signed (see Section 3.2 of RFC5280).  The certificate MAY contain an alternative name extension (Section 4.2.1.6 of RFC5280) that includes contact information.  Of the available options, an email address using the "rfc822Name" form or an HTTP RFC7230 (or HTTPS RFC2818) "uniformResourceIdentifier" SHOULD be included, though including other options are not prohibited. The offered end-entity certificate or the public key it contains becomes an identifier for the application server.  Push services are able to reduce the data they retain for an application server, either by extracting important information like the subject public key information (SPKI), by hashing, or a combination.  Of course, a push service might choose to ignore the provided information. To avoid requesting certificates from user agents, it might be necessary to serve requests from user agents and requests from application servers on different hostnames or port numbers. </del>  2.2. <del> In this model, the push service vends a token to each application server that requests it.  That token is kept secret and used as the basis for authentication. This doesn't address the need for contact information, but it addresses the need for a consistent application server identifier. A Cookie RFC6265 is a token of this nature.  All the considerations regarding the use (and misuse) of HTTP cookies apply should this option be chosen.  A mechanism that makes token theft more difficult, such as I-D.ietf-tokbind-https might be needed.  However that suggests a separate option (see tokbind). This information would be repeated with each request, but that overhead is greatly reduced by header compression RFC7541 in HTTP/2 RFC7540. 2.3. In this model, clients generates a token that it uses to prove ownership over a private key.  Use of the same key over time establishes a continuous identity. Push message requests can be accompanied by a JSON Web Token (JWT) RFC7519.  An "aud" (Audience) claim in the token MUST include the push resource URL.  This binds the token to a specific push subscription, but not a specific push message.  As a result, the token is reusable, limited by the value of the "exp" (Expiry) claim in the token.  An "exp" claim MUST be included. The JWT is included in an Authorization header field, using an auth- scheme of "WebPush". The definition of the "Bearer" auth-scheme in RFC6750 is almost perfect, but context would seem to indicate that this is only valid for use with OAuth. The corresponding public key is included in a JSON Web Key (JWK) RFC7517.  This would be included in either a newly-defined "jwk" parameter of the Crypto-Key header field I-D.ietf-httpbis-encryption- encoding; alternatively, the "p256ecdsa" parameter defined in I- D.thomson-http-content-signature could be used to transport a raw key. For voluntarily-provided contact details, a separate header field could be used (as in from) or the JWT could include claims about identity.  For the latter, the "sub" (subject) claim could include a contact URI for the application server. The JWT MUST use a JSON Web Signature (JWS) RFC7515.  Both the JWS and JWK MUST use an elliptic curve digital signature (ECDSA) key on the NIST P-256 curve FIPS186. A JWT also offers the option of including contact information as an additional claim.  An "iss" (Issuer) claim can include a contact URI: either a "mailto:" (email) RFC6068 or an "https:" RFC2818 SHOULD be used. 2.4. Contact information for an application server could be included in a header field, either directly (e.g., a From header field, Section 5.5.1 of RFC7231), or by reference (e.g., a new "contact" link relation RFC5988 that identified a vCard RFC6350).  Note that a From header field is limited to email addresses. Like an server- or client-vended token (server-token, client-token), contact information would need to be repeated, though that cost is reduced with HTTP/2. 2.5. Signing of push message requests would allow the push service to attribute requests to an application server based on an asymmetric key.  This could be done in any number of ways JWS RFC7515 and HTTP signatures I-D.cavage-http-signatures being the most likely options. Note that the latter does not provide a means of conveying the signing key, which would be necessary for this application. Request signing shares much in common with client-vended tokens client-token, but it removes any possibility of token reuse in the interests of security. Request signing has a few shortcomings: Deciding what to sign is challenging.  Signing only the body of a message is not sufficient to prevent message replay attacks. Every message contains a signature, which can increase the load on a server signficantly.  This is especially bad if a signature validation result is input to denial of service mitigation decision making. 2.6. The mechanism proposed in I-D.ietf-tokbind-https can be used to provide a stable identifier for application servers.  This includes a signature over material that is exported from the underlying TLS connection.  Importantly, this does not require a new signature for each request: the same signature is repeated for every request, HTTP/2 is again used to reduce the cost of the repeated information. Token binding could be used independently of cookies.  Consequently, an application server would not be required to accept and store cookies, though the push service would not be able to offload any state as a result. </del>  3. <del> A stable identifier for an application server - such as a public key or a token - could also be used to associate a subscription with the application server. </del>  <del> Subscription association reduces the reliance on endpoint secrecy by </del>  requiring proof of possession to be demonstrated by an application server when requesting delivery of a push message.  This provides an additional level of protection against leaking of the details of the push subscription. <del> 3.1. </del>  <del> The user agent includes the public key or token of the application server when requesting the creation of a subscription.  For example, the Web Push API API could allow an application to provide a public key as part of a new field on the "PushSubscriptionOptions" dictionary. </del>  <del> This token might then be added to the request to create a push subscription. </del>  <del> Allowing the inclusion of multiple keys when creating a subscription would allow a subscription to be associated with multiple application servers or application server instances.  This would require more state to be maintained by the push service for each subscription. </del>  <del> 3.2. </del>  <del> When a subscription has been associated with an application server, the request for push message delivery MUST include proof of </del>  possession for the associated private key or token that was used when <del> creating the subscription.  Requests that do not contain proof of possession are rejected with a 401 (Unauthorized) status code. </del>  <del> 4. </del>  <del> This document has no IANA actions (yet). </del>  <del> 5. </del>  <del> TLS 1.2 RFC5246 does not provide any confidentiality protections for client certificates.  A network attacker can therefore see the identification information that is provided by the application server.  A push service MAY choose to offer confidentiality protection for application server identity by initiating TLS renegotiation immediately after establishing the TLS connection at the cost of some additional latency.  Using TLS 1.3 I-D.ietf-tls- tls13 provides confidentiality protection for this information without additional latency. </del>  An application server might offer falsified contact information.  A push service operator therefore cannot use the presence of unvalidated contact information as input to any security-critical decision-making process. <del> Many of the alternative solutions are vulnerable to replay attacks. Applying narrow limits to the period over which a replayable token can be reused limits the potential value of a stolen token to an attacker and can increase the difficulty of stealing a token.  The token binding solution, which binds tokens to a single TLS connection can make tokens less reusable. </del>

As discussed on the mailing list. NAME NAME can you review this? You can see a nicely formatted version .
This looks good, thanks! +NAME to take a look from the server-side perspective (notably, we'd have to parse and extract a value from header on the server).
Updated.
I think that the confusion here between 401 and 403 were not helped by the fact that they were completely inconsistent. Here are the revised rules: MUST send 401 if you absolutely require credentials and there are none MAY send 403 if the credentials are bad
403 "forbidden" should not be sent if credentials are bad - would only happen if credentials are good ( we verified that the caller is who he claims to be ), but he is forbidden to send, because the subscribe request specified a different sender is allowed. 401 is for missing or bad credentials - if there was no JWT token but the server expects one, of if the JWT provided is bad, doesn't matches the signature. , Martin Thomson EMAIL wrote:
URL , Costin Manolache EMAIL wrote:
NAME I believe that the text is correct. "bad" was perhaps too terse, maybe I should have said "403 MAY be sent if the credentials are present but insufficient to authorize the request"
Thanks. Sorry for being too picky, but I've seen some nasty bugs caused by 401/403 confusion. 403 and "bad" or "invalid" credentials can be interpreted as "invalidate current password and ask user" - in webpush it shouldn't be a huge problem, since the JWT tokens will almost never be invalid (unlike a regular account on password change or revoked token ). , Martin Thomson EMAIL wrote:

An application server can voluntarily identify itself to a push service using the described technique.  This identification information can be used by the push service to attribute requests  <ins> that are made by the same application server to a single entity. This can used to reduce the secrecy for push subscription URLs by being able to restrict subscriptions to a specific application server.  An application server is further able include additional information the operator of a push service can use to contact the operator of the application server. </ins> 1. exposed to a greater risk of denial of service attack.  While requests from application servers can be indirectly attributed to user agents, this is not always efficient or even sufficient.  <ins> Providing more information about the application server directly to a push service allows the push service to better distinguish between legitimate and bogus requests. </ins> Additionally, this design also relies on endpoint secrecy as any application server in possession of the endpoint is able to send messages, albeit without payloads.  In situations where usage of a subscription can be limited to a single application server, the  <ins> ability to associate a subscription with the application server could reduce the impact of a data leak. 1.1. </ins> This document describes a system whereby an application server can volunteer information about itself to a push service.  At a minimum, preference over an unidentified application server when choosing whether to discard a push message.  <ins> 1.2. </ins> The words "MUST", "MUST NOT", "SHOULD", and "MAY" are used in this document.  It's not shouting, when they are capitalized, they have the special meaning described in RFC2119.  <ins> The terms "push message", "push service", "push subscription", "application server", and "user agent" are used as defined in I- D.ietf-webpush-protocol. </ins> 2.  <ins> Application servers SHOULD generate and maintain a signing key pair usable with elliptic curve digital signature (ECDSA) over the P-256 curve FIPS186.  Use of this key when sending push messages establishes a continuous identity for the application server. When requesting delivery of a push message, the application includes a JSON Web Token (JWT) RFC7519, signed using its signing key.  The token includes a number of claims as follows: An "aud" (Audience) claim in the token MUST include the unicode serialization of the origin (Section 6.1 of RFC6454) of the push resource URL.  This binds the token to a specific push service. This ensures that the token is reusable for all push resource URLs that share the same origin. An "exp" (Expiry) claim MUST be included with the time after which the token expires.  This limits the time that a token over which a token is valid.  An "exp" claim MUST NOT be more than 24 hours from the time of the request. This JWT is included in an Authorization header field, using an auth- scheme of "WebPush".  A push service MAY reject a request with a 403 (Forbidden) status code RFC7235 if the JWT signature or its claims are invalid. The JWT MUST use a JSON Web Signature (JWS) RFC7515.  The signature MUST use ECDSA on the NIST P-256 curve FIPS186, that is "ES256" RFC7518. </ins> 2.1.  <ins> If the application server wishes to provide the JWT MAY include an "sub" (Subject) claim.  The "sub" claim SHOULD include a contact URI for the application server as either a "mailto:" (email) RFC6068 or an "https:" RFC2818 URI. </ins> 2.2.  <ins> An application server requests the delivery of a push message as described in I-D.ietf-webpush-protocol.  If the application server wishes to self-identify, it includes an Authorization header field with credentials that use the "WebPush" authentication scheme auth and a Crypto-Key header field that includes its public key key. Note that the header fields shown in ex-push don't include line wrapping.  Extra whitespace is added to meet formatting constraints. This equates to a JWT with the header and body shown in ex-jwt.  This JWT would be valid until 2016-01-21T01:53:25Z RFC3339. The first part of the JWT is effectively fixed.  Would be it acceptable to require that that segment is omitted from the header field? </ins> 3.  <ins> A new "WebPush" HTTP authentication scheme RFC7235 is defined.  This authentication scheme carries a signed JWT, as described in jwt. This authentication scheme is for origin-server authentication only. Therefore, this authentication scheme MUST NOT be used with The Proxy-Authenticate or Proxy-Authorization header fields. This authentication scheme does not require a challenge.  Clients are able to generate the Authorization header field without any additional information from a server.  Therefore, a challenge for this authentication scheme MUST NOT be sent in a WWW-Authenticate header field. All unknown or unsupported parameters to "WebPush" authentication credentials MUST be ignored.  The "realm" parameter is ignored for this authentication scheme. 4. In order for the push service to be able to validate the JWT, it needs to learn the public key of the application server.  A "p256ecdsa" parameter is defined for the Crypto-Key header field I- D.ietf-httpbis-encryption-encoding to carry this information. The "p256ecdsa" parameter includes an elliptic curve digital signature algorithm (ECDSA) public key FIPS186 in uncompressed form X9.62 that is encoded using the URL- and filename-safe variant of base-64 RFC4648 with padding removed. Note that with push message encryption I-D.ietf-webpush-encryption, this results in two values in the Crypto-Key header field, one with the a "p256dh" key and another with a "p256ecdsa" key. JWK RFC7517 seems like the obvious choice here.  However, JWK doesn't define a compact representation for public keys, which complicates the representation of JWK in a header field. 5. The public key of the application server serves as a stable identifier for the server.  This key can be used to restrict a push subscription to a specific application server. </ins>  <ins> Subscription restriction reduces the reliance on endpoint secrecy by </ins> requiring proof of possession to be demonstrated by an application server when requesting delivery of a push message.  This provides an additional level of protection against leaking of the details of the push subscription.  <ins> 5.1. The user agent includes the public key of the application server when requesting that a push subscription.  This restricts use of the resulting push subscription to application servers that are able to provide proof of possession for the corresponding private key. </ins>  <ins> This public key is then added to the request to create a push subscription as described in key.  The Crypto-Key header field includes exactly one public key.  For example: </ins>  <ins> An application might use the Web Push API API to include this information.  For example, the API might permit an application to provide a public key as part of a new field on the "PushSubscriptionOptions" dictionary. </ins>  <ins> Allowing the inclusion of multiple keys when creating a subscription would allow a subscription to be associated with multiple application servers or application server instances. This might be more flexible, but it also would require more state to be maintained by the push service for each subscription. </ins>  <ins> 5.2. </ins>  <ins> When a push subscription has been associated with an application server, the request for push message delivery MUST include proof of </ins> possession for the associated private key or token that was used when  <ins> creating the push subscription. </ins>  <ins> A push service MUST reject a message that includes omits mandatory credentials with a 401 (Unauthorized) status code.  A push service MAY reject a message that includes invalid credentials with a 403 (Forbidden) status code.  Credentials are invalid if: </ins>  <ins> either the authentication credentials or public key are not included in the request, </ins>  <ins> the signature on the JWT cannot be successfully verified using the included public key, the current time is later than the time identified in the "exp" (Expiry) claim or more than 24 hours before the expiry time, the origin of the push resource is not included in the "aud" (Audience) claim, or the public key used to sign the doesn't match the one that was included in the creation of the push message. A push subscription that is not restricted to a particular key MAY still validate a token that is present, except for the last check.  A push service MAY then reject a request if the token is found to be invalid. In theory, since the push service was given a public key, the push message request could omit the public key.  On balance, this keeps things simple and it allows push services to compress the public key (by hashing it, for example).  In any case, the relatively minor space savings aren't particularly important on the connection between the application server and push service. A push service does not need to forward the JWT or public key to the user agent when delivering the push message. 6. </ins>  <ins> This authentication scheme is vulnerable to replay attacks if an attacker can acquire a valid JWT.  Applying narrow limits to the period over which a replayable token can be reused limits the potential value of a stolen token to an attacker and can increase the difficulty of stealing a token. </ins> An application server might offer falsified contact information.  A push service operator therefore cannot use the presence of unvalidated contact information as input to any security-critical decision-making process.  <ins> Validation of a signature on the JWT requires a non-trivial amount of computation.  For something that might be used to identify legitimate requests under denial of service attack conditions, this is not ideal.  Application servers are therefore encouraged to reuse a JWT, which permits the push service to cache the results of signature validation. 7. 7.1. This registers the "WebPush" authentication scheme in the "Hypertext Transfer Protocol (HTTP) Authentication Scheme Registry" established in RFC7235. WebPush auth of this document This scheme is origin-server only and does not define a challenge. 7.2. This registers a "p256ecdsa" parameter for the Crypto-Key header field in the "Hypertext Transfer Protocol (HTTP) Crypto-Key Parameters" established in I-D.ietf-httpbis-encryption-encoding. p256ecdsa Conveys a public key for that is used to generate an ECDSA signature. key of this document </ins>


Abstract An application server can use the method described to voluntarily <del> identify itself to a push service.  This identification information can be used by the push service to attribute requests that are made by the same application server to a single entity.  An application server can include additional information that the operator of a push service can use to contact the operator of the application server. This identification information can be used to restrict the use of a push subscription to a single application server. </del>  1. the protocol provides.  For these reasons, RFC8030 does not define a mandatory system for authentication of application servers. <del> An unfortunate consequence of this design is that a push service is exposed to a greater risk of denial of service attack.  While requests from application servers can be indirectly attributed to user agents, this is not always efficient or even sufficient. </del>  Providing more information about the application server directly to a push service allows the push service to better distinguish between legitimate and bogus requests. This JWT is included in an Authorization header field, using an auth- scheme of "vapid".  A push service MAY reject a request with a 403 (Forbidden) status code RFC7235 if the JWT signature or its claims <del> are invalid. </del>  The JWT MUST use a JSON Web Signature (JWS) RFC7515.  The signature MUST use ECDSA on the NIST P-256 curve FIPS186 which is identified as this authentication scheme. This authentication scheme is intended for use by an application <del> server when using the Web Push protocol RFC8030, but it could be used in other contexts if applicable. </del>  3.1. sources.  Secondarily, the X9.62 encoding is also considerably smaller. <del> Some implementations permit the same P-256 key to be used for signing and key exchange.  An application server MUST select a different private key for the key exchange I-D.ietf-webpush-encryption and </del>  signing the authentication token.  Though a push service is not obligated to check either parameter for every push message, a push service SHOULD reject push messages that have identical values for 4.1. <del> The user agent includes the public key of the application server when requesting the creation of a push subscription.  This restricts use of the resulting subscription to application servers that are able to provide proof of possession for the corresponding private key. The public key is then added to the request to create a push subscription.  The push subscription request is extended to include a body.  The body of the request is a JSON object as described in RFC7159.  A "vapid" member is added to this JSON object, containing the public key on the P-256 curve, encoded in the uncompressed form X9.62 and base64url encoded RFC7515.  The media type of the body is set to "application/webpush-options+json" (see mime for registration of this media type). A push service MUST ignore the body of a request that uses a different media type.  For the "application/webpush-options+json" media type, a push service MUST ignore any members on this object that it does not understand. </del>  The example in ex-restrict shows a restriction to the key used in ex- push.  Extra whitespace is added to meet formatting constraints. possession for the associated private key that was used when creating the push subscription. <del> A push service MUST reject a message that omits mandatory credentials with a 401 (Unauthorized) status code.  A push service MAY reject a message that includes invalid credentials with a 403 (Forbidden) status code.  Credentials are invalid if: </del>  either the authentication token or public key are not included in the request,

This looks a lot worse than it really is. Reflowing text causes massive diffs, which github somehow manages to make look like entirely new text.

Abstract An application server can use the method described to voluntarily  <ins> identify itself to a push service.  The "vapid" authentication scheme allows a client to include its an identity in a signed token with requests that it makes.  The signature can be used by the push service to attribute requests that are made by the same application server to a single entity.  The identification information can allow the operator of a push service to contact the operator of the application server.  The signature can be used to restrict the use of a push subscription to a single application server. </ins> 1. the protocol provides.  For these reasons, RFC8030 does not define a mandatory system for authentication of application servers.  <ins> An unfortunate consequence of the design of RFC8030 is that a push service is exposed to a greater risk of denial of service attack. While requests from application servers can be indirectly attributed to user agents, this is not always efficient or even sufficient. </ins> Providing more information about the application server directly to a push service allows the push service to better distinguish between legitimate and bogus requests. This JWT is included in an Authorization header field, using an auth- scheme of "vapid".  A push service MAY reject a request with a 403 (Forbidden) status code RFC7235 if the JWT signature or its claims  <ins> are invalid.  A push service MUST NOT use information from an invalid token. </ins> The JWT MUST use a JSON Web Signature (JWS) RFC7515.  The signature MUST use ECDSA on the NIST P-256 curve FIPS186 which is identified as this authentication scheme. This authentication scheme is intended for use by an application  <ins> server when using the Web Push protocol RFC8030. </ins> 3.1. sources.  Secondarily, the X9.62 encoding is also considerably smaller.  <ins> Some elliptic curve implementations permit the same P-256 key to be used for signing and key exchange.  An application server MUST select a different private key for the key exchange WEBPUSH-ENCRYPTION and </ins> signing the authentication token.  Though a push service is not obligated to check either parameter for every push message, a push service SHOULD reject push messages that have identical values for 4.1.  <ins> A user agent that wishes to create a restricted subscription includes the public key of the application server when requesting the creation of a push subscription.  This restricts use of the resulting subscription to application servers that are able to provide proof of possession for the corresponding private key. The user agent then adds the public key to the request to create a push subscription.  The push subscription request is extended to include a body.  The body of the request is a JSON object as described in RFC7159.  The user agent adds a "vapid" member to this JSON object that contains a public key on the P-256 curve, encoded in the uncompressed form X9.62 and base64url encoded RFC7515.  The media type of the body is set to "application/webpush-options+json" (see mime for registration of this media type). A push service can ignore the body of a request to create a subscription that uses a different media type.  For the "application/ webpush-options+json" media type, a push service MUST ignore any members on this object that it does not understand. </ins> The example in ex-restrict shows a restriction to the key used in ex- push.  Extra whitespace is added to meet formatting constraints. possession for the associated private key that was used when creating the push subscription.  <ins> A push service MUST reject a message sent to a restricted push subscription if that message includes no "vapid" authentication or invalid "vapid" authentication.  A 401 (Unauthorized) status code might be used if the authentication is absent; a 403 (Forbidden) status code might be used if authentication is invalid. "vapid" authentication is invalid if: </ins> either the authentication token or public key are not included in the request,


4.6. <del> Both Simulcast RFC8853 and Scalable Video Coding (SVC), including K-SVC (also known as "S modes", in which multiple encodings are sent on the same SSRC), MAY be supported by both the Media Servers and WHIP clients through negotiation in the SDP offer/answer. </del>  If the client supports simulcast and wants to enable it for publishing, it MUST negotiate the support in the SDP offer according simulcast offer MUST create an answer according to the procedures RFC8853 section 5.3.2.  4.7. In order to support future extensions to be defined for the WHIP

From NAME Simulcast and scalable video coding Both Simulcast [RFC8853] and Scalable Video Coding (SVC), including K-SVC (also known as "S modes", in which multiple encodings are sent on the same SSRC), MAY be supported by both the Media Servers and WHIP clients through negotiation in the SDP offer/answer. [BA] K-SVC and “S” modes are different. K-SVC denotes the KEY and KEY_SHIFT modes, whereas “S” modes denote the encapsulation of multiple encodings within a single SSRC, as is supported in VP9 and AV1. Diagrams of the various modes are included in the WebRTC-SVC specification: URL Also, SVC is not negotiated within Offer/Answer in WebRTC. It is something that the encoder can just turn on. At least for temporal modes (L1T2, L1T3) ingester support can often be taken for granted. While the VP9 and AV1 specifications require a compliant decoder to be able to decode any mode than an encoder can encode, in practice there are VP9 and AV1 hardware decoders that cannot decode spatial scalability because they do not support spatial references (e.g. a P-frame at a higher resolution than the P or I frame that it references). This nasty little “wrinkle” required us to define the “spatialScalability” attribute in Media Capabilities, to allow applications to discover whether a (hardware) decoder supports spatial scalability or not: Media Capabilities URL Not sure if you want to get into this in the specification. Issues are most likely to be encountered where hardware-based transcoders are used (but in that scenario, spatial scalability probably wouldn’t be relevant anyway),

4.6.  <ins> Simulcast as per RFC8853 MAY be supported by both the Media Servers and WHIP clients through negotiation in the SDP offer/answer. </ins> If the client supports simulcast and wants to enable it for publishing, it MUST negotiate the support in the SDP offer according simulcast offer MUST create an answer according to the procedures RFC8853 section 5.3.2. <ins> It is possible for both Media Servers and WHIP clients to support Scalable Video Coding (SVC).  However, as there is no universal negotiation mechanism in SDP for SVC, the encoder must consider the negotiated codec(s), intended usage, and SVC support in available decoders when configuring SVC. </ins> 4.7. In order to support future extensions to be defined for the WHIP


1. WebRTC intentionally does not specify a signaling transport protocol <del> at application level, while RTCWEB standardized the signalling </del>  protocol itself (JSEP, SDP O/A) and everything that was going over the wire (media, codec, encryption, ...).  This flexibility has <del> allowed for implementing a wide range of services.  However, those services are typically standalone silos which don't require </del>  interoperability with other services or leverage the existence of tools that can communicate with them. In the broadcasting/streaming world, the usage of hardware encoders <del> that would make it very simple to plug in (SDI) cables carrying raw media, encoding it in place, and pushing it to any streaming service or CDN ingest is ubiquitous.  Having to implement a custom signalling transport protocol for each different webrtc services has hindered adoption. </del>  <del> While some standard signalling protocols are available that can be </del>  integrated with WebRTC, like SIP or XMPP, they are not designed to be used in broadcasting/streaming services, and there also is no sign of <del> adoption in that industry.  RTSP, which is based on RTP and maybe the closest in terms of features to webrtc, is not compatible with WebRTC SDP offer/answer model. </del>  <del> In the specific case of ingest into a platform, some assumption can be made about the server-side which simplifies the webrtc compliance burden, as detailed in webrtc-gateway document I-D.draft-alvestrand- rtcweb-gateways. </del>  This document proposes a simple protocol for supporting WebRTC as <del> ingest method which is: </del>  Easy to implement, As easy to use as current RTMP URIs. <del> Fully compliant with Webrtc and RTCWEB specs. </del>  <del> Allow for both ingest in traditional media platforms for extension and ingest in webrtc end-to-end platform for lowest possible latency. </del>  Lowers the requirements on both hardware encoders and broadcasting <del> services to support webrtc. </del>  Usable both in web browsers and in native encoders. "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC2119. <del> WHIP client: WebRTC Media encoder or producer that acts as client on the WHIP protocol and encodes and delivers the media to a remote media server. </del>  WHIP endpoint: Ingest server receiving the initial WHIP request. WHIP endpoint URL: URL of the WHIP endpoint that will create the <del> WHIP resource </del>  <del> Media Server: WebRTC media server that establishes the media session with the WHIP client and receives the media produced by it. </del>  WHIP resource: Allocated resource by the WHIP endpoint for an <del> ongoing ingest session that the WHIP client can send request for </del>  altering the session (ICE operations or termination, for example). WHIP resource URL: URL allocated to a specific media session by <del> the WHIP endpoint which can be used to perform operations such </del>  terminating the session or ICE restarts. 3. The WebRTC-HTTP ingest protocol (WHIP) uses an HTTP POST request to perform a single shot SDP offer/answer so an ICE/DTLS session can be <del> established between the encoder/media producer and the broadcasting ingestion endpoint. </del>  Once the ICE/DTLS session is set up, the media will flow <del> unidirectionally from the encoder/media producer to the broadcasting ingestion endpoint.  In order to reduce complexity, no SDP renegotiation is supported, so no tracks or streams can be added or removed once the initial SDP O/A over HTTP is completed. </del>  4. to the WHIP endpoint configured URL. The HTTP POST request will have a content type of application/sdp and <del> contain the SDP offer as body.  The WHIP endpoint will generate an SDP answer and return it on a 201 Accepted response with content type of application/sdp and the SDP answer as body and a Location header pointing to the newly created resource. </del>  <del> SDP offer SHOULD use the sendonly attribute and the SDP answer MUST use the recvonly attribute. </del>  <del> Once a session is setup ICE consent freshness RFC7675 will be used to detect abrupt disconnection and DTLS teardown for session termination by either side. </del>  To explicitly terminate the session, the WHIP client MUST perform an <del> HTTP DELETE request to the resource url returned on the Location </del>  header of the initial HTTP POST.  Upon receiving the HTTP DELETE request, the WHIP resource will be removed and the resources freed on the media server, terminating the ICE and DTLS sessions. NAT, the WHIP media server SHOULD be publicly accessible. The initial offer by the WHIP client MAY be sent after the full ICE <del> gathering is complete containing the full list of ICE candidates, or only contain local candidates or even an empty list of candidates. </del>  The WHIP endpoint SDP answer SHALL contain the full list of ICE candidates publicly accessible of the media server.  The media server The WHIP client MAY perform trickle ICE or an ICE restarts RFC8863 by sending a HTTP PATCH request to the WHIP resource URL with a body <del> containing a SDP fragment with mime type "application/trickle-ice- sdpfrag" as specified in RFC8840 with the new ice candidate or ice ufrag/pwd for ice restarts.  A WHIP resource MAY not support either trickle ICE (i.e.  ICE lite media servers) or ICE restart, and it MUST return a 405 Method Not Allowed for any HTTP PATCH request. </del>  A WHIP client receiving a 405 response for an HTTP PATCH request SHALL not send further request for ICE trickle or restart.  If the WHIP client gathers additional candidates (via STUN/TURN) after the <del> SDP offer is sent, it MUST send STUN request to the ICE candidates received from the media server as per RFC8838 regardless if the HTTP PATCH is supported by either the WHIP client or the WHIP resource. </del>  4.2. WHIP endpoints and media servers MAY not be colocated on the same server so it is possible to load balance incoming requests to different media servers.  WHIP clients SHALL support HTTP redirection <del> via 307 Temporary Redirect response code. </del>  <del> In case of high load, the WHIP endpoints may return a 503 (Service </del>  Unavailable) status code indicating that the server is currently unable to handle the request due to a temporary overload or scheduled maintenance, which will likely be alleviated after some delay. Configuration of the TURN or STUN servers used by the WHIP client is out of the scope of this document. <del> It is RECOMMENDED that broadcasting server provides an HTTP interface for provisioning the TUNR/STUN servers url and short term credentiasl as in I-D.draft-uberti-behave-turn-rest-00.  Note that the authentication information or the url of this API are not related to the WHIP enpoint URLs or authentication. </del>  <del> It could also be possilble to configure the STUN/TURN server URLS and long term credentials provided by the either broadcasting service or an external TURN provider. </del>  4.5. <del> Authentication and authorization is supported by the Authorization HTTP header with a bearer token as per RFC6750. </del>  4.6. Both simulcast and scalable video coding (including K-SVC modes) MAY <del> be supported by both media servers and WHIP clients and negotiated in the SDP O/A. </del>  If the client supports simulcast and wants to enable it for publishing, it MUST negotiate the support in the SDP offer according extensions is defined. Protocol extensions supported by the WHIP server MUST be advertised <del> to the WHIP client on the 201 created response to initial HTTP POST request to the WHIP enpoint by inserting one Link header for each extension with the extension "rel" type attribute and the uri for the HTTP resource that will be available for receiving request related to that extension. </del>  <del> Protocol extensions are optionasl for bot WHIP clients and servers. </del>  WHIP clients MUST ignore any Link attribute with an unknown "rel" attribute value and WHIP servers MUST not require the usage of any of the extensions. For example, taking a potential extension of server to client communication using server sent events as specified in https://html.spec.whatwg.org/multipage/server-sent- <del> events.html#server-sent-events, the url for connecting to the server </del>  side event resource for the published stream will be returned in the <del> initial HTTP "201 Created" response with a "Link" header an a "rel" </del>  attribute of "urn:ietf:params:whip:server-sent-events". The HTTP 201 response to the HTTP POST request would look like:

I gave the spec a good read through and would like to propose some minor language edits as my first contribution. Most of these are straight forward such as: WebRTC not webrtc URI not uri signaling not signalling offer/answer not O/A some grammatical changes There is one somewhat significant correction here in that the header on the example WHIP endpoint reply pointed at the RFC for the extension. I believe this is incorrect and the intent is that this points at a WHIP resource. I have updated the example as such.

1. WebRTC intentionally does not specify a signaling transport protocol  <ins> at application level, while RTCWEB standardized the signaling </ins> protocol itself (JSEP, SDP O/A) and everything that was going over the wire (media, codec, encryption, ...).  This flexibility has  <ins> allowed the implementation of a wide range of services.  However, those services are typically standalone silos which don't require </ins> interoperability with other services or leverage the existence of tools that can communicate with them. In the broadcasting/streaming world, the usage of hardware encoders  <ins> that make it very simple to plug in (SDI) cables carrying raw media, encode it in place, and push it to any streaming service or CDN ingest is already ubiquitous.  It is the adoption of a custom signaling transport protocol for each WebRTC service has hindered broader adoption as an ingestion protocol. </ins>  <ins> While some standard signaling protocols are available that can be </ins> integrated with WebRTC, like SIP or XMPP, they are not designed to be used in broadcasting/streaming services, and there also is no sign of  <ins> adoption in that industry.  RTSP, which is based on RTP and may be the closest in terms of features to WebRTC, is not compatible with the WebRTC SDP offer/answer model. </ins>  <ins> In the specific case of media ingestion into a streaming service, some assumptions can be made about the server-side which simplifies the WebRTC compliance burden, as detailed in webrtc-gateway document I-D.draft-alvestrand-rtcweb-gateways. </ins> This document proposes a simple protocol for supporting WebRTC as  <ins> media ingestion method which is: </ins> Easy to implement, As easy to use as current RTMP URIs.  <ins> Fully compliant with WebRTC and RTCWEB specs. </ins>  <ins> Allows for both ingest in traditional media platforms and ingest in WebRTC end-to-end platforms with the lowest possible latency. </ins> Lowers the requirements on both hardware encoders and broadcasting  <ins> services to support WebRTC. </ins> Usable both in web browsers and in native encoders. "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC2119.  <ins> WHIP client: WebRTC media encoder or producer that acts as a client of the WHIP protocol by encoding and delivering the media to a remote media server. </ins> WHIP endpoint: Ingest server receiving the initial WHIP request. WHIP endpoint URL: URL of the WHIP endpoint that will create the  <ins> WHIP resource. </ins>  <ins> Media Server: WebRTC media server or consumer that establishes the media session with the WHIP client and receives the media produced by it. </ins> WHIP resource: Allocated resource by the WHIP endpoint for an  <ins> ongoing ingest session that the WHIP client can send requests for </ins> altering the session (ICE operations or termination, for example). WHIP resource URL: URL allocated to a specific media session by  <ins> the WHIP endpoint which can be used to perform operations such as </ins> terminating the session or ICE restarts. 3. The WebRTC-HTTP ingest protocol (WHIP) uses an HTTP POST request to perform a single shot SDP offer/answer so an ICE/DTLS session can be  <ins> established between the encoder/media producer (WHIP client) and the broadcasting ingestion endpoint (media server). </ins> Once the ICE/DTLS session is set up, the media will flow  <ins> unidirectionally from the encoder/media producer (WHIP client) to the broadcasting ingestion endpoint (media server).  In order to reduce complexity, no SDP renegotiation is supported, so no tracks or streams can be added or removed once the initial SDP offer/answer over HTTP is completed. </ins> 4. to the WHIP endpoint configured URL. The HTTP POST request will have a content type of application/sdp and  <ins> contain the SDP offer as the body.  The WHIP endpoint will generate an SDP answer and return a 201 Accepted response with a content type of application/sdp and the SDP answer as the body and a Location header pointing to the newly created resource. </ins>  <ins> The SDP offer SHOULD use the sendonly attribute and the SDP answer MUST use the recvonly attribute. </ins>  <ins> Once a session is setup, ICE consent freshness RFC7675 will be used to detect abrupt disconnection and DTLS teardown for session termination by either side. </ins> To explicitly terminate the session, the WHIP client MUST perform an  <ins> HTTP DELETE request to the resource URL returned in the Location </ins> header of the initial HTTP POST.  Upon receiving the HTTP DELETE request, the WHIP resource will be removed and the resources freed on the media server, terminating the ICE and DTLS sessions. NAT, the WHIP media server SHOULD be publicly accessible. The initial offer by the WHIP client MAY be sent after the full ICE  <ins> gathering is complete with the full list of ICE candidates, or only contain local candidates or even an empty list of candidates. </ins> The WHIP endpoint SDP answer SHALL contain the full list of ICE candidates publicly accessible of the media server.  The media server The WHIP client MAY perform trickle ICE or an ICE restarts RFC8863 by sending a HTTP PATCH request to the WHIP resource URL with a body  <ins> containing a SDP fragment with MIME type "application/trickle-ice- sdpfrag" as specified in RFC8840 with the new ICE candidate or ICE ufrag/pwd for ICE restarts.  A WHIP resource MAY not support trickle ICE (i.e.  ICE lite media servers) nor ICE restart, and it MUST return a 405 Method Not Allowed for any HTTP PATCH request. </ins> A WHIP client receiving a 405 response for an HTTP PATCH request SHALL not send further request for ICE trickle or restart.  If the WHIP client gathers additional candidates (via STUN/TURN) after the  <ins> SDP offer is sent, it MUST send a STUN request to the ICE candidates received from the media server as per RFC8838 regardless of the HTTP PATCH supported by either the WHIP client or the WHIP resource. </ins> 4.2. WHIP endpoints and media servers MAY not be colocated on the same server so it is possible to load balance incoming requests to different media servers.  WHIP clients SHALL support HTTP redirection  <ins> via the 307 Temporary Redirect response code. </ins>  <ins> In case of high load, the WHIP endpoints MAY return a 503 (Service </ins> Unavailable) status code indicating that the server is currently unable to handle the request due to a temporary overload or scheduled maintenance, which will likely be alleviated after some delay. Configuration of the TURN or STUN servers used by the WHIP client is out of the scope of this document.  <ins> It is RECOMMENDED that the broadcasting server provides an HTTP interface for provisioning the STUN/TURN servers' URLs and short term credentials as in I-D.draft-uberti-behave-turn-rest-00.  Note that neither the authentication information nor the URLs of the STUN/TURN servers are related to the WHIP endpoint. </ins>  <ins> It is also possible to configure the STUN/TURN server URLs with long term credentials provided by either the broadcasting service or an external TURN provider. </ins> 4.5.  <ins> Authentication and authorization MAY be supported on the WHIP endpoint and the WHIP resource by providing the Authorization HTTP header with a bearer token as per RFC6750. </ins> 4.6. Both simulcast and scalable video coding (including K-SVC modes) MAY  <ins> be supported by both the media servers and WHIP clients through negotiation in the SDP offer/answer. </ins> If the client supports simulcast and wants to enable it for publishing, it MUST negotiate the support in the SDP offer according extensions is defined. Protocol extensions supported by the WHIP server MUST be advertised  <ins> to the WHIP client on the 201 Created response to the initial HTTP POST request sent to the WHIP endpoint.  The WHIP endpoint MUST return one Link header for each extension with the extension "rel" type attribute and the URI for the HTTP resource that will be available for receiving requests related to that extension. </ins>  <ins> Protocol extensions are optional for both WHIP clients and servers. </ins> WHIP clients MUST ignore any Link attribute with an unknown "rel" attribute value and WHIP servers MUST not require the usage of any of the extensions. For example, taking a potential extension of server to client communication using server sent events as specified in https://html.spec.whatwg.org/multipage/server-sent-  <ins> events.html#server-sent-events, the URL for connecting to the server </ins> side event resource for the published stream will be returned in the  <ins> initial HTTP "201 Created" response with a "Link" header and a "rel" </ins> attribute of "urn:ietf:params:whip:server-sent-events". The HTTP 201 response to the HTTP POST request would look like:


Abstract <del> While WebRTC has been very successful in a wide range of scenarios, </del>  its adoption in the broadcasting/streaming industry is lagging behind.  Currently there is no standard protocol (like SIP or RTSP) <del> designed for ingesting media in a streaming service, and content providers still rely heavily on protocols like RTMP for it. These protocols are much older than webrtc and lack by default some important security and resilience features provided by webrtc with minimal delay. The media codecs used in older protocols do not always match those being used in WebRTC, mandating transcoding on the ingest node, introducing delay and degrading media quality.  This transcoding step is always present in traditional streaming to support e.g.  ABR, and comes at no cost.  However webrtc implements client-side ABR, also called Network-Aware Encoding by e.g.  Huavision, by means of simulcast and SVC codecs, which otherwise alleviate the need for server-side transcoding.  Content protection and Privacy Enhancement can be achieved with End-to-End Encryption, which preclude any server-side media processing. </del>  This document proposes a simple HTTP based protocol that will allow <del> WebRTC endpoints to ingest content into streaming services and/or CDNs to fill this gap and facilitate deployment. </del>  1.

I'd like to propose removing the mention of a specific company/brand in the abstract as well as some clarification around the language used to describe the protocol and why it is important/different from "other protocols".

Abstract  <ins> While WebRTC has been very sucessful in a wide range of scenarios, </ins> its adoption in the broadcasting/streaming industry is lagging behind.  Currently there is no standard protocol (like SIP or RTSP)  <ins> designed for ingesting media into a streaming service using WebRTC and so content providers still rely heavily on protocols like RTMP for it. These protocols are much older than WebRTC and by default lack some important security and resilience features provided by WebRTC with minimal overhead and additional latency. The media codecs used for ingestion in older protocols tend to be limited and not negotiated.  WebRTC includes support for negotiation of codecs, potentially alleviating transcoding on the ingest node (wich can introduce delay and degrade media quality).  Server side transcoding that has traditionally been done to present multiple renditions in Adaptive Bit Rate Streaming (ABR) implementations can be replaced with simulcasting and SVC codecs that are well supported by WebRTC clients.  In addition, WebRTC clients can adjust client- side encoding parameters based on RTCP feedback to maximize encoding quality. Encryption is mandatory in WebRTC, therefore secure end-to-end transport of media is implicit. </ins> This document proposes a simple HTTP based protocol that will allow  <ins> WebRTC based ingest of content into streaming servics and/or CDNs. </ins> 1.


Abstract <del> While WebRTC has been very sucessful in a wide range of scenarios, </del>  its adoption in the broadcasting/streaming industry is lagging behind.  Currently there is no standard protocol (like SIP or RTSP) designed for ingesting media into a streaming service using WebRTC The media codecs used for ingestion in older protocols tend to be limited and not negotiated.  WebRTC includes support for negotiation of codecs, potentially alleviating transcoding on the ingest node <del> (wich can introduce delay and degrade media quality).  Server side </del>  transcoding that has traditionally been done to present multiple renditions in Adaptive Bit Rate Streaming (ABR) implementations can be replaced with simulcasting and SVC codecs that are well supported media is implicit. This document proposes a simple HTTP based protocol that will allow <del> WebRTC based ingest of content into streaming servics and/or CDNs. </del>  1. MUST return a 405 Method Not Allowed response for any HTTP PATCH request. <del> A WHIP resource receving a PATH request with new ICE candidates, but which does not perform an ICE restart, MUST return a 204 No content response without body. </del>  If the HTTP PATCH request results in an ICE restart, the WHIP resource SHALL return a 200 OK with an "application/trickle-ice- sdpfrag" body containing the new ICE username fragment and password <del> and, optionaly, the new set of ICE candidates for the media server. </del>  As the HTTP PATCH request sent by a WHIP client may be received out of order by the WHIP resource, the WHIP resource SHOULD keep track of HTTP POST request to the WHIP endpoint url. Each ICE server will be returned on a Link header with a "rel" <del> attribribute value of "ice-server" where the Link target URI is the ICE server URL and the credentials are encoded in the Link target </del>  attributes as follows: username: If the Link header represents a TURN server, and <del> creadential-type is "password", then this attribute specifies the </del>  username to use with that TURN server. <del> credential: If credential-type attribute is misson or has a </del>  "password" value, the credential attribute represents a long-term authentication password, as described in RFC8489, Section 10.2. WHIP endpoints and resources MAY require the HTTP request to be authenticated using an HTTP Authorization header with a Bearer token <del> as specified in RFC6750 section 2.1.  WHIP clients MUST implemenent </del>  this authentication and authorization mechanism and send the HTTP Authorization header in all HTTP request sent to either the WHIP endpoint or resource. The nature, syntax and semantics of the bearer token as well as how to distribute it to the client is outside the scope of this document. <del> Some examples ot the kind of tokens that could be used are, but are </del>  not limited to, JWT tokens as per RFC6750 and RFC8725 or a shared secret stored on a database.  The tokens are typically made available to the end user alongside the WHIP endpoint url and configured on the WHIP clients. WHIP endpoints and resources COULD perform the authentication and <del> authorization by encoding an authentication token withing the urls for the WHIP endpoints or resources instead.  In case the WHIP client is not configured to use a bearer token the HTTP Authorization header </del>  must not be sent in any request. 4.6. If the client supports simulcast and wants to enable it for publishing, it MUST negotiate the support in the SDP offer according to the procedures in RFC8853 section 5.3.  A server accepting a <del> simulcast offer MUST create an answer accoding to the procedures </del>  RFC8853 section 5.3.2. 4.7.

If you find them useful, here are some spelling fixes. The ' PATH ' spelling is confusing, I think it should be ' PATCH ' Also the draft URL points to and older draft. I have been very inspired by WHIP, thank you for giving it to the community.

Abstract  <ins> While WebRTC has been very successful in a wide range of scenarios, </ins> its adoption in the broadcasting/streaming industry is lagging behind.  Currently there is no standard protocol (like SIP or RTSP) designed for ingesting media into a streaming service using WebRTC The media codecs used for ingestion in older protocols tend to be limited and not negotiated.  WebRTC includes support for negotiation of codecs, potentially alleviating transcoding on the ingest node  <ins> (which can introduce delay and degrade media quality).  Server side </ins> transcoding that has traditionally been done to present multiple renditions in Adaptive Bit Rate Streaming (ABR) implementations can be replaced with simulcasting and SVC codecs that are well supported media is implicit. This document proposes a simple HTTP based protocol that will allow  <ins> WebRTC based ingest of content into streaming services and/or CDNs. </ins> 1. MUST return a 405 Method Not Allowed response for any HTTP PATCH request.  <ins> A WHIP resource receiving a PATCH request with new ICE candidates, but which does not perform an ICE restart, MUST return a 204 No content response without body. </ins> If the HTTP PATCH request results in an ICE restart, the WHIP resource SHALL return a 200 OK with an "application/trickle-ice- sdpfrag" body containing the new ICE username fragment and password  <ins> and, optionally, the new set of ICE candidates for the media server. </ins> As the HTTP PATCH request sent by a WHIP client may be received out of order by the WHIP resource, the WHIP resource SHOULD keep track of HTTP POST request to the WHIP endpoint url. Each ICE server will be returned on a Link header with a "rel"  <ins> attribute value of "ice-server" where the Link target URI is the ICE server URL and the credentials are encoded in the Link target </ins> attributes as follows: username: If the Link header represents a TURN server, and  <ins> credential-type is "password", then this attribute specifies the </ins> username to use with that TURN server.  <ins> credential: If credential-type attribute is missing or has a </ins> "password" value, the credential attribute represents a long-term authentication password, as described in RFC8489, Section 10.2. WHIP endpoints and resources MAY require the HTTP request to be authenticated using an HTTP Authorization header with a Bearer token  <ins> as specified in RFC6750 section 2.1.  WHIP clients MUST implement </ins> this authentication and authorization mechanism and send the HTTP Authorization header in all HTTP request sent to either the WHIP endpoint or resource. The nature, syntax and semantics of the bearer token as well as how to distribute it to the client is outside the scope of this document.  <ins> Some examples of the kind of tokens that could be used are, but are </ins> not limited to, JWT tokens as per RFC6750 and RFC8725 or a shared secret stored on a database.  The tokens are typically made available to the end user alongside the WHIP endpoint url and configured on the WHIP clients. WHIP endpoints and resources COULD perform the authentication and  <ins> authorization by encoding an authentication token within the urls for the WHIP endpoints or resources instead.  In case the WHIP client is not configured to use a bearer token the HTTP Authorization header </ins> must not be sent in any request. 4.6. If the client supports simulcast and wants to enable it for publishing, it MUST negotiate the support in the SDP offer according to the procedures in RFC8853 section 5.3.  A server accepting a  <ins> simulcast offer MUST create an answer according to the procedures </ins> RFC8853 section 5.3.2. 4.7.


MUST return a 405 Method Not Allowed response for any HTTP PATCH request.  A WHIP resource receiving a PATCH request with new ICE candidates, but which does not perform an ICE restart, MUST return a 204 No <del> content response without body. </del>  If the HTTP PATCH request results in an ICE restart, the WHIP resource SHALL return a 200 OK with an "application/trickle-ice- sdpfrag" body containing the new ICE username fragment and password <del> and, optionally, the new set of ICE candidates for the media server. As the HTTP PATCH request sent by a WHIP client may be received out of order by the WHIP resource, the WHIP resource SHOULD keep track of the previous values of the ICE username fragment and client used by the WHIP client.  If an HTTP PATCH request is received with a previously used ICE username fragment and password by the client, the WHIP endpoint SHALL NOT perform and ICE restart but reject the request with a 409 Conflict response instead. </del>  4.2. "password" value, the credential attribute represents a long-term authentication password, as described in RFC8489, Section 10.2. <del> credential-type: If the Link header represents represents a TURN server, then this attribute specifies how the credential attribute value should be used when that TURN server requests authorization. The default value if the attribute is not present is "password". </del>  There are some webrtc implementations that do not support updating the ICE server configuration after the local offer has been created. authenticated using an HTTP Authorization header with a Bearer token as specified in RFC6750 section 2.1.  WHIP clients MUST implement this authentication and authorization mechanism and send the HTTP <del> Authorization header in all HTTP request sent to either the WHIP </del>  endpoint or resource. The nature, syntax and semantics of the bearer token as well as how attribute value and WHIP servers MUST NOT require the usage of any of the extensions. <del> Each protocol extension MUST register an unique "rel" attribute values at IANA starting with the prefix: "urn:ietf:params:whip:". </del>  For example, taking a potential extension of server to client communication using server sent events as specified in

As per
thank you NAME added new changes per your feedback
PATCH request may be received out of order, how do we handle that? ICE candidate, ICE restart reversed order: ICE candidate with old ufrag should be discarded ICE restart, ICE candidate reversed order: Should ICE candidate trigger ICE restart anyway? Agreed solution: use Etag for requests/responses

MUST return a 405 Method Not Allowed response for any HTTP PATCH request. <ins> As the HTTP PATCH request sent by a WHIP client may be received out of order by the WHIP resource, the WHIP resource MUST generate a unique strong entity-tag identifying the ICE session as per RFC7232 section 2.3.  The initial value of the entity-tag identifying the initial ICE session MUST be returned in an ETag header in the 201 response to the initial POST request to the WHIP endpoint and in the 200 OK of a PATCH request that triggers an ICE restart. A WHIP client sending a PATCH request for performing trickle ICE MUST contain an If-Match header with the latest known entity-tag as per RFC7232 section 3.1.  When the PATCH request is received by the WHIP resource, it MUST compare the entity-tag value requested with the current entinty-tag of the resource as per RFC7232 section 3.1 and return a 412 Precondition Failed response if they do not match. Entity-tag validation MUST only be used for HTTP requests requiring to match a known ICE session and SHOULD NOT be used otherwise, for example in the HTTP DELETE request to terminate the session. </ins> A WHIP resource receiving a PATCH request with new ICE candidates, but which does not perform an ICE restart, MUST return a 204 No  <ins> content response without body.  If the media server does not support a candidate transport or is not able to resolve the connection address it MUST accept the HTTP request with the 204 response and silently discard the candidate. A WHIP client sending a PATCH request for performing ICE restart MUST contain an If-Match header with a field-value "*" as per RFC7232 section 3.1. </ins> If the HTTP PATCH request results in an ICE restart, the WHIP resource SHALL return a 200 OK with an "application/trickle-ice- sdpfrag" body containing the new ICE username fragment and password  <ins> and, optionally, the new set of ICE candidates for the media server and the new entity-tag correspond to the new ICE session in an ETag response header. If the ICE request can not be performed by the WHIP resource it MUST return an appropriate HTTP error code but MUST NOT terminate the session immediately.  The WHIP client COULD try again to perform a new ICE restart or terminate the session issuing a HTTP DELETE request instead.  In any case the session MUST be terminated if the ICE consent expires as a consequence of the failed ICE restart. Given that in order to send new ICE candidates to the WHIP resource, the WHIP client needs to know the entity-tag associated to the ICE session, it MUST buffer any gathered candidates before the HTTP response to the initial PUT request or the PATCH request with the new entity-tag value is received.  Once the entity-tag value is known the WHIP client SHOULD send a single aggregated HTTP PATCH request with all the ICE candidates it has buffered so far. </ins> 4.2. "password" value, the credential attribute represents a long-term authentication password, as described in RFC8489, Section 10.2.  <ins> credential-type: If the Link header represents a TURN server, then this attribute specifies how the credential attribute value should be used when that TURN server requests authorization.  The default value if the attribute is not present is "password". </ins> There are some webrtc implementations that do not support updating the ICE server configuration after the local offer has been created. authenticated using an HTTP Authorization header with a Bearer token as specified in RFC6750 section 2.1.  WHIP clients MUST implement this authentication and authorization mechanism and send the HTTP  <ins> Authorization header in all HTTP requests sent to either the WHIP </ins> endpoint or resource. The nature, syntax and semantics of the bearer token as well as how attribute value and WHIP servers MUST NOT require the usage of any of the extensions.  <ins> Each protocol extension MUST register a unique "rel" attribute values at IANA starting with the prefix: "urn:ietf:params:whip:". </ins> For example, taking a potential extension of server to client communication using server sent events as specified in


sending a HTTP PATCH request to the WHIP resource URL with a body containing a SDP fragment with MIME type "application/trickle-ice- sdpfrag" as specified in RFC8840 with the new ICE candidate or ICE <del> ufrag/pwd for ICE restarts.  A WHIP resource MAY not support trickle ICE (i.e.  ICE lite media servers) or ICE restart, in that case, it MUST return a 405 Method Not Allowed response for any HTTP PATCH request. </del>  As the HTTP PATCH request sent by a WHIP client may be received out of order by the WHIP resource, the WHIP resource MUST generate a

While this is not ambiguous, it might be read as "MAY NOT". I suggest rewording as "Support for trickle ICE by WHIP resources is OPTIONAL".
NAME wdyt? is it ok to merge it and will this solve your concerns?
Yes, that's much better.

sending a HTTP PATCH request to the WHIP resource URL with a body containing a SDP fragment with MIME type "application/trickle-ice- sdpfrag" as specified in RFC8840 with the new ICE candidate or ICE  <ins> ufrag/pwd for ICE restarts. Trickle ICE and ICE restart support is OPTIONAL for a WHIP resource. If Trickle ICE or ICE restarts are not supported by the WHIP resource, it MUST return a 405 Method Not Allowed response for any HTTP PATCH request. </ins> As the HTTP PATCH request sent by a WHIP client may be received out of order by the WHIP resource, the WHIP resource MUST generate a


contain an If-Match header with the latest known entity-tag as per RFC7232 section 3.1.  When the PATCH request is received by the WHIP resource, it MUST compare the entity-tag value requested with the <del> current entinty-tag of the resource as per RFC7232 section 3.1 and </del>  return a 412 Precondition Failed response if they do not match. <del> Entity-tag validation MUST only be used for HTTP requests requiring to match a known ICE session and SHOULD NOT be used otherwise, for example in the HTTP DELETE request to terminate the session. </del>  A WHIP resource receiving a PATCH request with new ICE candidates, but which does not perform an ICE restart, MUST return a 204 No

So it's a MUST or a SHOULD?
NAME wdyt? is it ok to merge it and will it solve your concerns?
I'm sorry, but I still don't know what that says. Does it say that the client MUST NOT use If-Match on the DELETE, or does it say that the server MUST ignore an If-Match on the DELETE? I suggest making it clear to whom the requirement applies.
should be applicable only to clients, is it better now?
NAME ping?
I think this is still ambiguous due to the MUST in the first part. I suggest removing the first part:
what about now?
NAME ping?
merging this, we can modify it after the WGLC
Yeah, it's okay now.

contain an If-Match header with the latest known entity-tag as per RFC7232 section 3.1.  When the PATCH request is received by the WHIP resource, it MUST compare the entity-tag value requested with the  <ins> current entity-tag of the resource as per RFC7232 section 3.1 and </ins> return a 412 Precondition Failed response if they do not match.  <ins> WHIP clients SHOULD NOT use entity-tag validation when matching a specific ICE session is not required, such as for example when initiating a DELETE request in order to terminate a session. </ins> A WHIP resource receiving a PATCH request with new ICE candidates, but which does not perform an ICE restart, MUST return a 204 No


Abstract While WebRTC has been very sucessful in a wide range of scenarios, <del> its adption in the broadcasting/streaming industry is lagging behind. Currently there is no standard protocol (like SIP or RTSP) designed for ingesting media in a streaming service, and content providers still rely heavily on protocols like RTMP for it. </del>  These protocols are much older than webrtc and lack by default some important security and resilience features provided by webrtc with The media codecs used in older protocols do not always match those being used in WebRTC, mandating transcoding on the ingest node, introducing delay and degrading media quality.  This transcoding step <del> is always present in traditionnal streaming to support e.g.  ABR, and </del>  comes at no cost.  However webrtc implements client-side ABR, also called Network-Aware Encoding by e.g.  Huavision, by means of simulcast and SVC codecs, which otherwise alleviate the need for side media processing. This document proposes a simple HTTP based protocol that will allow <del> WebRTC endpoings to ingest content into streaming servics and/or CDNs </del>  to fill this gap and facilitate deployment. 1. In the specific case of ingest into a platform, some assumption can be made about the server-side which simplifies the webrtc compliance <del> burden, as detailled in webrtc-gateway document. </del>  https://tools.ietf.org/html/draft-ietf-rtcweb-gateways-02 <del> This document proposse a simple protocol for supporting WebRTC as </del>  ingest method which is: - Easy to implement, - As easy to use as current RTMP URI.  - Fully compliant with Webrtc and RTCWEB specs.  - <del> Allow for both ingest in traditionnal media platforms for extention </del>  and ingest in webrtc end-to-end platform for lowest possible latency. - Lowers the requirements on both hardware encoders and broadcasting services to support webrtc.  - Usable both in web browsers and in 4.4. <del> Authtentication and authorization is supported by the Authorization HTTP header with a bearear token as per RFC6750. </del>  4.5.

Authtentication, bearear, proposse, detailled, endpoings, adption, traditionnal.
Thank you very much!

Abstract While WebRTC has been very sucessful in a wide range of scenarios,  <ins> its adoption in the broadcasting/streaming industry is lagging behind.  Currently there is no standard protocol (like SIP or RTSP) designed for ingesting media in a streaming service, and content providers still rely heavily on protocols like RTMP for it. </ins> These protocols are much older than webrtc and lack by default some important security and resilience features provided by webrtc with The media codecs used in older protocols do not always match those being used in WebRTC, mandating transcoding on the ingest node, introducing delay and degrading media quality.  This transcoding step  <ins> is always present in traditional streaming to support e.g.  ABR, and </ins> comes at no cost.  However webrtc implements client-side ABR, also called Network-Aware Encoding by e.g.  Huavision, by means of simulcast and SVC codecs, which otherwise alleviate the need for side media processing. This document proposes a simple HTTP based protocol that will allow  <ins> WebRTC endpoints to ingest content into streaming servics and/or CDNs </ins> to fill this gap and facilitate deployment. 1. In the specific case of ingest into a platform, some assumption can be made about the server-side which simplifies the webrtc compliance  <ins> burden, as detailed in webrtc-gateway document. </ins> https://tools.ietf.org/html/draft-ietf-rtcweb-gateways-02  <ins> This document proposes a simple protocol for supporting WebRTC as </ins> ingest method which is: - Easy to implement, - As easy to use as current RTMP URI.  - Fully compliant with Webrtc and RTCWEB specs.  -  <ins> Allow for both ingest in traditional media platforms for extention </ins> and ingest in webrtc end-to-end platform for lowest possible latency. - Lowers the requirements on both hardware encoders and broadcasting services to support webrtc.  - Usable both in web browsers and in 4.4.  <ins> Authentication and authorization is supported by the Authorization HTTP header with a bearer token as per RFC6750. </ins> 4.5.


WHIP client SHOULD send a single aggregated HTTP PATCH request with all the ICE candidates it has buffered so far.  4.2. In order to reduce the complexity of implementing WHIP in both

If you have more than one ice-restart PATCH request in flight at once, it'll be unclear to the server which one was sent first. This ambiguity is bad; it won't be clear which selected ICE candidate pair to switch to. One simple solution would simply be to forbid this, but Sergio pointed out at the meeting that this might be problematic if your device fell off its network (because it might not get the response to the first ice-restart, so would have to wait for it to time out). If so we need another way to resolve the ambiguity.
Would sending a header (rfc7232) on the response help solving the issue?
I'm not adept enough with HTTP semantics to be certain, but it seems like it could? It'd mean servers are required to respond to at most once ICE restart per second. That adds some implementation complexity, but doesn't seem like an enormous limitation.
Right, the timestamp has only second accuracy, so it would not work if both patch requests have been received in the same second. This is however kind of an edge case in an edge case. Could we just state that if both ice restarts are received with same the client should send a new ice restart request? All the other alternatives seems uglier and more complex.
Basing it on "if two were received" doesn't let the server know which one the client is using, in the case where one of the responses wasn't received (because the whole mess was triggered by a network failure). However, in that case one of the ICE handshakes won't succeed, so the server can just continue with the (hopefully) succeeding one. I agree this is an edge case of an edge case.
I think I have worded my comment badly. Let's back and see which would be the problematic case. The client will update its ICE username fragment and pwd before sending the PATH request and the server will restart ice when receiving a new PATCH request with an updated ice username fragment/pwd. I don't think that there is any issue at all if any of the requests or responses are not received by either side. The issue happens when client has sent two PATCH requests (first with username client1 and second with client2) and the server receives them out of order and generates two responses one with server 1 and the later with server 2. So the client would be using client2:server1 and the server server2:client1. The header would allow us to know (up to a 1s of resolution) which request has been processed first by the server, but would not allow us to solve the problem, and the client would have to send a new Ice restart request in order to get to a good state. The other alternative is always send an with the last know etag, that would prevent the server for processing out of order ice restart request, but it would prevent the ice restart from working if the previous response was lost and we don't know the value of the actual server etag.
Let us please not use in new protocols. It causes a number of complications which implementers are likely to get wrong (dealing with sub-second transactions, interaction with , etc.). Let's please stick to ETags only.
Thinking about this further, both and have the wrong semantic. The semantic we need is that we need the client to define an order to ICE restarts, and then the server should reject or ignore ICE restart requests that arrive out of order. (This is the semantic that SIP achieves with .) One possibility would be to use the header for this, but I don't know how appropriate that would be, or if it fits the semantic for that header. (This would still have the at-most-one-per-second problem, but in principle the client could "cheat" by bumping the seconds field on subsequent requests, so long as there wasn't a steady state of more than one ICE restart per second.). Pinging NAME [does that work?] as the author of URL Are there any better HTTP client headers for this purpose? Is this a terrible idea?
Just thinking aloud... Send PATCH with If-Match. If you get 412, resynchronise using HEAD and try again?
If-Match with which ETag? Remember the worrying case is where you send the second request before the response to the first request has arrived. (And yes, if interfaces are flapping, it's possible for it to turn out that there are to be three (or more) outstanding requests...)
The last one the client got. If it's obsolete (which is likely after a failrure), client gets 412, gets the last ETag using HEAD, then resends with the right ETag.
That means (at least) 3 RTTs to recover from a network failure, which isn't great, but I agree it's probably the easiest solution protocol-wise. A double ICE restart like this should hopefully be a pretty rare phenomenon.
NAME Agreed on both counts.
How about not making the protocol harder and let the client deal with it by sending a new ICE restart in case there are receive an out of order response and ICE is not in state?
NAME NAME what do you think about my previous comment?
NAME The problem is that receiving a response out of order doesn't necessarily mean that that request was processed out of order, and vice-versa. Also, the out-of-order response might not be received, because this will be happening at times of network flakiness. I like NAME suggestion, but it would mean defining HEAD (and thus presumably GET) on the WHIP resource URL in order to get resync working, which isn't great.
I have re-read my previous comment, and it does not make any sense in fact. Let me try again to rephrase my thoughts. The server response order is irrelevant. When the client performs an ICE restart, it discards the ice username/pwd frags, so if there was a previous request pending to receive an answer it must be discarded. So only the response to the last sent request is relevant to the client. So the key question is detecting out of order request at the server. Instead of trying to resolve it at HTTP level, we could just apply the ICE info received by the server and wait for the ICE connection states. If there is a mismatch between the information at the client and at the server (because an out of order request), the STUN request will contain an invalid ICE info and will be rejected by the server. In terms of webrtc w3c apis, this would trigger an ice or which would be an indication for the client to perform a new ICE restart. Depending on the local candidates, it may require the ice request to timeout (30s?) but it would be the client would eventually recover. The client could also optimize this by adding a timeout to receive the state to start a new ice restart (as already done by many non trickle ice services to not have to wait for candidates in private networks).
So you're arguing that we make the ICE restart best-effort, and rely on the application to trigger a new restart in the rare case when the previous restart failed. That makes a lot of sense. However, I'm a little concerned this will cause unacceptable latency (see RFC 8863).
We are talking about an edge case of an edge case on unstable networks.. best effort is more than enough IMHO.. the alternative is complicating a lot the protocol..
I reluctantly agree. I still think the failure should be signalled explicitly at the HTTP layer, at the very least it will make troubleshooting easier.
NAME NAME wdyt?
Why not require that the server indicate the mismatch to the client, e.g. with HTTP 409?
because the server has no way of detecting the out of order requests El vie, 13 may 2022 14:29, Juliusz Chroboczek NAME escribió:
I'll switch my brain on next time. Sorry.
NAME NAME any feedback on this? I would love to update the draft asap and to a WGLC on it..
I feel we should go into LC with the issue open.
It sounds like I'm in the rough on making the protocol more complex, so if you want to write up your solution as a PR I'm willing to review it to make sure it makes sense.
NAME the PR is in here: URL

WHIP client SHOULD send a single aggregated HTTP PATCH request with all the ICE candidates it has buffered so far. <ins> In case of unstable network conditions, the ICE restart HTTP PATCH requests and responses might be received out of order.  In order to mitigate this scenario, when the client performs an ICE restart, it MUST discard any previous ice username/pwd frags and ignore any further HTTP PATCH response received from a pending HTTP PATCH request and apply only the ICE information received in the response to the last sent request.  If there is a mismatch between the ICE information at the client and at the server (because of an out of order request), the STUN requests will contain invalid ICE info and will be rejected by the server.  When this situation is detected by the WHIP Client it SHOULD send a new ICE restart request to the server. </ins> 4.2. In order to reduce the complexity of implementing WHIP in both


used for ICE restarts, it will contain a new ICE ufrag/pwd pair. Trickle ICE and ICE restart support is OPTIONAL for a WHIP resource. <del> If Trickle ICE or ICE restarts are not supported by the WHIP </del>  resource, it MUST return a 405 Method Not Allowed response for any <del> HTTP PATCH request. </del>  As the HTTP PATCH request sent by a WHIP client may be received out- of-order by the WHIP resource, the WHIP resource MUST generate a

fix for
Unsure if trickle ICE is mandatory for webrtc or not, but it is optional for the APP point of view: as per rfc8829, 3.5.2. ICE Candidate Trickling: However I think it would not harm to point it out in Section 4.2
PR available here: URL
Is it legal for a server to support Trickle ICE but not ICE Restarts? If that's the case, then the use of 405 is somewhat misleading, since the PATCH method is allowed, just not for ICE Restarts.
I think you are correct, if patch request is not supported the server must return a 405 response, if only ice restarts are not supported it should return a 501 Not Implemented.
Does WebRTC mandate support of ICE restart and trickle ICE? If so, should the WHIP optional support be mentioned in Section 4.2 (WebRTC Constraints)?

used for ICE restarts, it will contain a new ICE ufrag/pwd pair. Trickle ICE and ICE restart support is OPTIONAL for a WHIP resource.  <ins> If both Trickle ICE or ICE restarts are not supported by the WHIP </ins> resource, it MUST return a 405 Method Not Allowed response for any  <ins> HTTP PATCH request.  If the WHIP resource supports either Trickle ICE or ICE restarts, but not both, it MUST return a 501 Not Implemented for the HTTP PATCH requests that are not supported. </ins> As the HTTP PATCH request sent by a WHIP client may be received out- of-order by the WHIP resource, the WHIP resource MUST generate a


muxing SHALL be supported by both the WHIP client and the media server. <del> Unlike the behavior defined by RFC5763, a WHIP client MAY use a setup attribute value of setup:active in the SDP offer, in which case the WHIP endpoint MUST use a setup attribute value of setup:passive in the SDP answer. </del>  Tricke ICE and ICE restarts support is OPTIONAL for both the WHIP clients and media servers as explained in section 4.1.

The text says: "Unlike [RFC5763] a WHIP client MAY use a setup attribute value of setup:active in the SDP offer, in which case the WHIP endpoint MUST use a setup attribute value of setup:passive in the SDP answer." First, check whether it would be useful to also reference RFC 8842. Second, I think it is a BAD idea to go against the "MUST use setup:actpass" text in RFC 5763. Since you specify that the answerer MUST use setup:passive, there is no reason why the offer couldn't use setup:actpass, following the standard.
The idea is to prevent the WHIP client to have to implement active and passive setup. The MUST for the server is only in case that the client uses the setup attribute, maybe some rewording helps
You can still use the MUST for the server, even if the client uses 'actpass'.
Yes, we could, but would it be worthy? If the client sends , server MUST send . If the client sends , then the client MUST support to receive either an or response from the server, so I don't think we should put any extra requirement on the server. If the media server wants to only implement they are allowed in any case.
The document specifies the behavior of the media server, so even if the standard allows both 'active' and 'passive' you can still specify that a WHIP compliant server MUST send 'passive'. It is better than having the client do something which is not standard compliant.
ok, I get your point. The idea would be then to ask the client to send on the offer, despite only supporting the part, and force the media server to reply , right? Not sure if I like it or not, will ping the mailing list for consensus.
Yes. Specify that a WHIP-compliant media server MUST reply 'passive'.
If a MUST has to be added on servers, I think it should be 'active', not passive. It's an unwritten convention in basically all WebRTC applications that who receives the offer will send 'active', and while a convention is not a rule, forcing a change in this pattern would break a lot of implementations out there that may want to support WHIP on the server side.
Which is exactly why I wanted the original language that the client could say setup:active to indicate that it only implements DTLS client. Which isn't as unlikely as you might think, especially on devices with a secure element providing the DTLS certificate. It makes no sense to have an offer of actpass and then not actually allow both replies. Either you believe in the O/A model or you don't. By the way all my 'server' devices send answers with setup:passive because they are servers so running a DTLS server makes perfect sense. Seems to work fine...
An implementation can of course send whatever it wants, including setup:active. There is nothing anyone can do about that :) But I don't think we should standardize such behavior. As far as the WebRTC and SDP O/A standards are concerned, the offerer can act as both DTLS client and server. If that is the wrong assumption, then I think it shall be discussed in the affected WGs, and based on those discussions potentially update RFC 5763, 8839 etc. I don't think a standards document shall discard MUSTs just because we don't want to support required functionality. But then it should not matter if the offer contains setup:actpass, should it? :)
I fully agree with Tim. WHIP complicane with WebRTC means that WebRTC endpoints (or whatever name we give to them) can act like a WHIP client, but not all WHIP client needs to be fully compliant WebRTC endpoints. For the server side we are already reducing the requirements of a JSEP client as explained in the gateway draft: So, I would challenge that reducing the requirements on the WHIP client makes WHIP non-webrtc compliant. The idea behing this change is that there is no need for a whip client talking to a whip server to have to implement both active and passive setup. Negotiating actpass when only one mode is supported seems completelly wrong to me.
We've already found out that Tim always sends passive from servers, while Janus always sends active when it receives an offer: this means that whatever you force on the WHIP client will break one of the two servers. I think clients should send actpass as the RFC says.
Mandating clients to implement both active and passive is a no go for me. The goal has always been to reduce the burden on the clients because there was none available. Increasing the complexity of implementing them is not going to help.
btw, I think that Tim is referring that his servers respond as passive, while their clients sends active. So his (whip) clients would be able to talk with janus server, which is what we intended.
No, they wouldn't, because Janus expects actpass when it receives an offer, and will set the role of active for itself. Two actives won't get anywhere.
When you say 'clients', what exactly are you referring to? The WebRTC library that you are using in the application?
No, I am referring to the WHIP clients
Imagine I have a smart camera acting as a WHIP source which can only do Active DTLS (because of a hardware limitation). Let's assume when it tries to talk to Janus it will fail because Janus will only do active. If the camera signals this in it's WHIP offer with setup:active then the O/A fails early with a sensible error message http status:402 If it sends a (mendacious) setup:actpass then the connection will silently fail after ice connects and a 16 second DTLS timeout. So sending setup:active in the offer is the right thing for the camera to do. The other option is to say that such hardware shouldn't be doing WHIP, which seems like a needless limitation on hardware encoder design.
Incidentally I checked my (open source) Whipi client and it actually sends ! Which is why it works with Janus. (The target hardware (raspberry pi) does not have a secure element, so it is just a code size simplification not a hardware limitation - It still halves the complexity of the DTLS layer by only having to implement dtls server)
Back to the High level point. The WebRTC spec was designed to be Peer-to-Peer - so it makes sense that both sides need equal capabilities since you never know who will initiate an offer - so mandating actpass in the offer is a good idea. WISH/WHIP is explicitly client-server so asymmetry is to be expected. I would argue that the original wording is wrong however - "WHIP endpoint MUST use a setup attribute value of setup:passive in the SDP answer." Should read "WHIP endpoint SHOULD use a setup attribute value of setup:passive in the SDP answer. Or if it does not support passive it MUST reply with an http 402 error status and an explanation error message."
I think it shall be MUST. If the server cannot do that for whatever reason it will obviously have to return an error. We can for sure specify which error code to use. Also, I think it is better to say that the server MUST follow the procedures in RFC 4573. Regarding the WHIP client, a compromise would be to say that it SHOULD use actpass, according to 4573, unless it only implements the DTLS client role in which case it can use active. Because, we should not forbid a WHIP client from using the standard 4573 behavior if it is able to do so. In addition, there could be a note saying a few words about why a WHIP client might only implement the DTLS client role.
Here is some new text suggestion (I have not created a PR yet) for Section 4.2. Note that I also modify the BUNDLE text. The SDP BUNDLE mechanism [RFC8843] MUST be used by both WHIP clients and media servers. Each m- line MUST be part of a single BUNDLE group. Hence, when a WHIP client sends an SDP offer, it MUST include a bundle-only attribute in each bundled m- line. In addition, per [8843] the WHIP client and media server will use RTP/RTCP multiplexing for all bundled media. The WHIP client and media server SHOULD include the rtcp-mux-only attribute in each bundled m- line. When a WHIP client sends an SDP offer, it SHOULD use the setup:actpass attribute, as defined in [RFC5763]. However, if the WHIP client only implements the DTLS client role, it MAY use the setup:active attribute. NOTE: [RFC5763] defines that the offerer must use the setup:actpass attribute. However, the WHIP client will always communicate with a media server that is expected to support the DTLS server role, in which case the client might choose to only implement support for the DTLS client role.
I like that and I think it is a good compromise, creating the PR now
I have split it in two PRs so we can review/merge them independently: BUNDLE: URL SETUP: URL The include the proposed changes by NAME with a bit of rewording to match the notation of the referenced RFCs, and include that the server SHOULD response with a 422 error if the setup:active is not supported.

muxing SHALL be supported by both the WHIP client and the media server.  <ins> When a WHIP client sends an SDP offer, it SHOULD insert an SDP "setup" attribute with an "actpass" attribute value, as defined in RFC8842.  However, if the WHIP client only implements the DTLS client role, it MAY use an SDP "setup" attribute with an "active" attribute value.  If the WHIP endpoint does not support an SDP offer with an SDP "setup" attribute with an "active" attribute value, it SHOULD reject the request with a 422 Unprocessable Entity response. NOTE: RFC8842 defines that the offerer must insert an SDP "setup" attribute with an "actpass" attribute value.  However, the WHIP client will always communicate with a media server that is expected to support the DTLS server role, in which case the client might choose to only implement support for the DTLS client role. </ins> Tricke ICE and ICE restarts support is OPTIONAL for both the WHIP clients and media servers as explained in section 4.1.