idnits 2.17.1 draft-dunglas-mercure-01.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- == The page length should not exceed 58 lines per page, but there was 1 longer page, the longest (page 1) being 459 lines Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The document seems to lack an Introduction section. ** The document seems to lack a Security Considerations section. ** The document seems to lack an IANA Considerations section. (See Section 2.2 of https://www.ietf.org/id-info/checklist for how to handle the case when there are no actions for IANA.) ** There is 1 instance of too long lines in the document, the longest one being 8 characters in excess of 72. ** The document seems to lack a both a reference to RFC 2119 and the recommended RFC 2119 boilerplate, even if it appears to use RFC 2119 keywords. RFC 2119 keyword, line 64: '... The keywords MUST, MUST NOT, REQUIR...' RFC 2119 keyword, line 65: '... SHOULD NOT, RECOMMENDED, MAY, and O...' RFC 2119 keyword, line 84: '... Any hub MAY implement its own po...' RFC 2119 keyword, line 88: '... The publisher SHOULD advertises the...' RFC 2119 keyword, line 91: '...ub, so the subscriber MAY subscribe to...' (55 more instances...) Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year == The expression 'MAY NOT', while looking like RFC 2119 requirements text, is not defined in RFC 2119, and should not be used. Consider using 'MUST NOT' instead (if that is what you mean). Found 'MAY NOT' in this paragraph: An application CAN send events directly to the subscribers, without using an external hub server, if it is able to do so. In this case, it *MAY NOT* implement the endpoint to publish updates. -- The document date (11 October 2018) is 2024 days in the past. Is this intentional? Checking references for intended status: Informational ---------------------------------------------------------------------------- -- Missing reference section? 'RFC2119' on line 373 looks like a reference -- Missing reference section? 'RFC7230' on line 396 looks like a reference -- Missing reference section? 'RFC2818' on line 378 looks like a reference -- Missing reference section? 'RFC5988' on line 387 looks like a reference -- Missing reference section? 'RFC6902' on line 419 looks like a reference -- Missing reference section? 'RFC7386' on line 423 looks like a reference -- Missing reference section? 'RFC6570' on line 391 looks like a reference -- Missing reference section? 'RFC4287' on line 415 looks like a reference -- Missing reference section? 'RFC7515' on line 401 looks like a reference -- Missing reference section? 'RFC4122' on line 382 looks like a reference -- Missing reference section? 'RFC7516' on line 405 looks like a reference -- Missing reference section? 'RFC7517' on line 409 looks like a reference Summary: 5 errors (**), 0 flaws (~~), 3 warnings (==), 13 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 Network Working Group K. Dunglas 3 Internet-Draft Les-Tilleuls.coop 4 Intended status: Informational 11 October 2018 5 Expires: 14 April 2019 7 The Mercure Protocol 8 draft-dunglas-mercure-01 10 Abstract 12 Mercure is a protocol allowing to push data updates to web browsers 13 and other HTTP clients in a fast, reliable and battery-efficient way. 14 It is especially useful to publish real-time updates of resources 15 served through web APIs, to reactive web and mobile apps. 17 Status of This Memo 19 This Internet-Draft is submitted in full conformance with the 20 provisions of BCP 78 and BCP 79. 22 Internet-Drafts are working documents of the Internet Engineering 23 Task Force (IETF). Note that other groups may also distribute 24 working documents as Internet-Drafts. The list of current Internet- 25 Drafts is at https://datatracker.ietf.org/drafts/current/. 27 Internet-Drafts are draft documents valid for a maximum of six months 28 and may be updated, replaced, or obsoleted by other documents at any 29 time. It is inappropriate to use Internet-Drafts as reference 30 material or to cite them other than as "work in progress." 32 This Internet-Draft will expire on 14 April 2019. 34 Copyright Notice 36 Copyright (c) 2018 IETF Trust and the persons identified as the 37 document authors. All rights reserved. 39 This document is subject to BCP 78 and the IETF Trust's Legal 40 Provisions Relating to IETF Documents (http://trustee.ietf.org/ 41 license-info) in effect on the date of publication of this document. 42 Please review these documents carefully, as they describe your rights 43 and restrictions with respect to this document. Code Components 44 extracted from this document must include Simplified BSD License text 45 as described in Section 4.e of the Trust Legal Provisions and are 46 provided without warranty as described in the Simplified BSD License. 48 Table of Contents 50 1. Terminology 51 2. Discovery 52 3. Subscriptions 53 4. Hub 54 5. Authorization 55 6. Re-Connection and State Reconciliation 56 7. Encryption 57 8. References 58 8.1. Normative References 59 8.2. Informative References 60 Author's Address 62 1. Terminology 64 The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, 65 SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL, when they appear in this 66 document, are to be interpreted as described in [RFC2119]. 68 * Topic: An HTTP [RFC7230] or HTTPS [RFC2818] topic URL. The unit 69 to which one can subscribe to changes. 71 * Publisher: An owner of a topic. Notifies the hub when the topic 72 feed has been updated. As in almost all pubsub systems, the 73 publisher is unaware of the subscribers, if any. Other pubsub 74 systems might call the publisher the "source". Typically a 75 website or a web API. 77 * Subscriber: A client application that subscribes to real-time 78 updates of topics (typically a Progressive Web App or a Mobile 79 App). 81 * Hub: A server that handles subscription requests and distributes 82 the content to subscribers when the corresponding topics have been 83 updated (a Hub implementation is provided in this repository). 84 Any hub MAY implement its own policies on who can use it. 86 2. Discovery 88 The publisher SHOULD advertises the URL of one or more hubs to the 89 subscriber, allowing it to receive live updates when topics are 90 updated. If more than one hub URL is specified, it is expected that 91 the publisher notifies each hub, so the subscriber MAY subscribe to 92 one or more of them. 94 The publisher SHOULD include at least one Link Header [RFC5988] with 95 "rel=mercure" (a hub link header). The target URL of these links 96 MUST be a hub implementing the Mercure protocol. 98 Note: this relation type has not been registered yet [RFC5988]. 99 During the meantime, the relation type "https://git.io/mercure" can 100 be used instead. 102 The publisher MAY provide the following target attributes in the Link 103 headers: 105 * "last-event-id": the globally unique identifier of the last event 106 dispatched by the publisher at the time of the generation of this 107 resource. If provided, it MUST be passed to the hub through a 108 query parameter called "Last-Event-ID" and will be used to ensure 109 that possible updates having been made during between the resource 110 generation time and the connection to the hub are not lost. See 111 section #Re-Connection-and-State-Reconciliation). If this 112 attribute is provided, the publisher MUST always set the "id" 113 parameter when sending updates to the hub. 115 * "content-type": the content type of the updates that will pushed 116 by the hub. If omited, the subscriber MUST assume that the 117 content type will be the same than the one of the original 118 resource. Setting the "content-type" attribute is especially 119 useful to hint that partial updates will be pushed, using formats 120 such as JSON Patch [RFC6902] or JSON Merge Patch [RFC7386]. 122 * "key-set=": the key(s) to decrypt updates encoded in the 123 JWKS (JSON Web Key Set) format (see the Encryption section). 125 All these attributes are optional. 127 The publisher MAY also include one Link Header [RFC5988] with 128 "rel=self" (the self link header). It SHOULD contain the canonical 129 URL for the topic to which subscribers are expected to use for 130 subscriptions. If the Link with "rel=self" is ommitted, the current 131 URL of the resource MUST be used as fallback. 133 Minimal example: 135 GET /books/foo.jsonld HTTP/1.1 136 Host: example.com 138 HTTP/1.1 200 Ok 139 Content-type: application/ld+json 140 Link: ; rel="mercure" 142 {"@id": "/books/foo.jsonld", "foo": "bar"} 144 Links embedded in HTML or XML documents (as defined in the WebSub 145 recommendation) MAY also be supported by subscribers. 147 Note: the discovery mechanism described in this section is strongly 148 inspired from the one specified in the WebSub recommendation 149 (https://www.w3.org/TR/websub/#discovery). 151 3. Subscriptions 153 The subscriber subscribes to an URL exposed by a hub to receive 154 updates of one or many topics. To subscribe to updates, the client 155 opens an HTTPS connection following the Server-Sent Events 156 specification (https://html.spec.whatwg.org/multipage/server-sent- 157 events.html) to the hub's subscription URL advertised by the 158 Publisher. The connection SHOULD use HTTP/2 to leverage mutliplexing 159 and other advanced features of this protocol. 161 The subscriber specifies the list of topics to get updates for by 162 using one or several query parameters named "topic". The value of 163 these query parameters MUST be URI templates [RFC6570]. 165 Note: an URL is also a valid URI template. 167 The protocol doesn't specify the maximum number of "topic" parameters 168 that can be sent, but the hub MAY apply an arbitrary limit. 170 The EventSource JavaScript interface 171 (https://html.spec.whatwg.org/multipage/server-sent-events.html#the- 172 eventsource-interface) MAY be used to establish the connection. Any 173 other appropriate mechanism including but not limited to readable 174 streams (https://developer.mozilla.org/en- 175 US/docs/Web/API/Streams_API/Using_readable_streams) and 176 XMLHttpRequest (https://developer.mozilla.org/en- 177 US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest) (used by popular 178 polyfills) MAY also be used. 180 The hub sends updates concerning all subscribed resources matching 181 the provided URI templates. The hub MUST send these updates as text/ 182 event-stream compliant events 183 (https://html.spec.whatwg.org/multipage/server-sent-events.html#sse- 184 processing-model). 186 The "data" property MUST contain the new version of the topic. It 187 can be the full resource, or a partial update by using formats such 188 as JSON Patch "@RFC6902" or JSON Merge Patch "@RFC7386". 190 All other properties defined in the Server-Sent Events specification 191 MAY be used and SHOULD be supported by hubs. 193 The resource SHOULD be represented in a format with hypermedia 194 capabilities such as JSON-LD [W3C.REC-json-ld-20140116], Atom 195 [RFC4287], XML [W3C.REC-xml-20081126] or HTML [W3C.REC- 196 html52-20171214]. 198 Web Linking [RFC5988] SHOULD be used to indicate the IRI of the 199 resource sent in the event. When using Atom, XML or HTML as 200 serialization format for the resource, the document SHOULD contain a 201 "link" element with a "self" relation containing the IRI of the 202 resource. When using JSON-LD, the document SHOULD contain an "@id" 203 property containing the IRI of the resource. 205 Example: 207 // The subscriber subscribes to updates for the https://example.com/foo topic 208 // and to any topic matching https://example.com/books/{name} 209 const url = new URL('https://hub.example.com/subscribe'); 210 url.searchParams.append('topic', 'https://example.com/foo'); 211 url.searchParams.append('topic', 'https://example.com/bar/{id}'); 213 const eventSource = new EventSource(url); 215 // The callback will be called every time an update is published 216 eventSource.onmessage = function ({data}) { 217 console.log(data); 218 }; 220 4. Hub 222 The hub receives updates from the publisher on a dedicated HTTPS 223 endpoint. The connection MUST use an encryption layer, such as TLS. 224 HTTPS certificate can be obtained for free using Let's Encrypt 225 (https://letsencrypt.org/). 227 When it receives an update, the hub dispatches it to subsribers using 228 the established server-sent events connections. 230 An application CAN send events directly to the subscribers, without 231 using an external hub server, if it is able to do so. In this case, 232 it *MAY NOT* implement the endpoint to publish updates. 234 The endpoint to publish updates is an HTTPS URL accessed using the 235 "POST" method. The request MUST be encoded using the "application/x- 236 www-form-urlencoded" format and contains the following data: 238 * "topic": IRIs of the updated topic. If this key is present 239 several times, the first occurence is considered to be the 240 canonical URL of the topic, and other ones are considered to be 241 alternate URLs. The hub MUST dispatch this update to subscribers 242 subscribed to both canonical or alternate URLs. 244 * "data": the content of the new version of this topic 246 * "target" (optional): target audience of this event, see the 247 Authorization section for further information. 249 * "id" (optional): the topic's revision identifier, it will be used 250 as the SSE's "id" property, if omited the hub MUST generate a 251 valid UUID. 253 * "type" (optional): the SSE's "event" property (a specific event 254 type) 256 * "retry" (optional): the SSE's "retry" property (the reconnection 257 time) 259 The request MUST also contain an "Authorization" HTTP header 260 containing the string "Bearer" followed by a valid JWS [RFC7515] in 261 compact serialization that the hub will check to ensure that the 262 publisher is authorized to publish the update. 264 5. Authorization 266 If a topic is not public, the update request sent by the publisher to 267 the hub MUST also contain a list of keys named "target". Theirs 268 values are "string". They can be, for instance a user ID, or a list 269 of group IDs. 271 To receive updates for private topics, the subscriber MUST send a 272 cookie called "mercureAuthorization" when connecting to the hub. 274 The cookie SHOULD be set by the publisher during the discovery. The 275 cookie SHOULD have the "Secure", "HttpOnly". It MAY have the 276 "SameSite" flag if appropriate. Setting the cookie's "Path" to the 277 path of the subscribe endpoint is also RECOMMENDED. When skipping 278 the discovery mechanism, the client MAY set the cookie itself (for 279 security reasons, this is not recommended in the context of a web 280 browser). 282 Consequently if the subscriber is a web browser, both the publisher 283 and the hub have to share the same second level domain to use the 284 autorization feature. The "Domain" flag MAY be used to allow the 285 publisher and the host to use different subdomains. 287 By the "EventSource" specification, connections can only be 288 estabilished using the "GET" HTTP method, and it is not possible to 289 set custom HTTP headers (such as the "Authorization" one). 291 However, cookies are supported, and can be included even in 292 crossdomain requests if the CORS credentials are set 293 (https://html.spec.whatwg.org/multipage/server-sent-events.html#dom- 294 eventsourceinit-withcredentials): 296 The value of this cookie MUST be a JWS in compact serialization. It 297 MUST have a claim named "mercureTargets" that contains an array of 298 strings: the list of targets the user is authorized to receive 299 updates for. For instance, valid targets can be a username or a list 300 of group identifiers. The JWS SHOULD be short lived, especially if 301 the subscriber is a web browser. 303 If one or more targets are specified, the update MUST NOT be sent to 304 the subscriber by the hub, unless the "mercureTargets" claim of the 305 subscriber contains at least one target specified for the topic by 306 the publisher. 308 When using the authorization mechanism, the connection between the 309 subscriber and the hub MUST use an encryption layer (HTTPS is 310 required). 312 6. Re-Connection and State Reconciliation 314 To allow re-establisment in case of connection lost, events 315 dispatched by the hub SHOULD include an "id" property. The value 316 contained in this "id" property SHOULD be a globally unique 317 identifier. To do so, UUID [RFC4122] MAY be used. 319 According to the server-sent events specification, in case of 320 connection lost the subscriber will try to automatically reconnect. 321 During the reconnection the subscriber MUST send the last received 322 event id in a Last-Event-ID (https://html.spec.whatwg.org/multipage/ 323 iana.html#last-event-id) HTTP header. 325 The server-sent events specification doesn't allow to set this HTTP 326 header during the first connection (before a re-connection occurs). 327 In order to fetch any update dispatched between the initial resource 328 generation by the publisher and the connection to he hub, the 329 subscriber MUST send the event id provided during the discovery in 330 the "last-event-id" link's attribute in a query parameter named 331 "Last-Event-ID" when connecting to the hub. 333 If both the "Last-Event-ID" HTTP header and the query parameter are 334 present, the HTTP header MUST take precedence. 336 If the "Last-Event-ID" header or query parameter exists, the hub 337 SHOULD send to the subscriber all events published since the one 338 having this identifier. 340 The hub MAY discard some messages for operational reasons. The 341 subscriber MUST NOT assume that no update will be lost, and MUST re- 342 fetch the original topic to ensure this (for instance, after a long 343 deconnection time). 345 The hub MAY also specify the reconnection time using the "retry" key, 346 as specified in the server-sent events format. 348 7. Encryption 350 Using HTTPS doesn't prevent the hub to access to the update's 351 content. Depending of the intended privacy of informations contained 352 in the updates, it MAY be necessary to prevent eavesdropping by the 353 hub. 355 To make sure that the message content can not be read by the hub, the 356 publisher MAY encode the message before sending it to the hub. The 357 publisher SHOULD use JSON Web Encryption [RFC7516] to encrypt the 358 update content. The publisher MAY provide the relevant encryption 359 key(s) in the "key-set" attribute of the Link HTTP header during the 360 discovery. The "key-set" attribute SHOULD contain a key encoded 361 using the JSON Web Key Set [RFC7517] format. Any other out-of-band 362 mechanism MAY be used instead to share the key between the publisher 363 and the subscriber. 365 Updates encyption is considered a best practice to prevent mass 366 surveillance. This is especially relevant if the hub is managed by 367 an external provider. 369 8. References 371 8.1. Normative References 373 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 374 Requirement Levels", BCP 14, RFC 2119, 375 DOI 10.17487/RFC2119, March 1997, . 378 [RFC2818] Rescorla, E., "HTTP Over TLS", RFC 2818, 379 DOI 10.17487/RFC2818, May 2000, . 382 [RFC4122] Leach, P., Mealling, M., and R. Salz, "A Universally 383 Unique IDentifier (UUID) URN Namespace", RFC 4122, 384 DOI 10.17487/RFC4122, July 2005, . 387 [RFC5988] Nottingham, M., "Web Linking", RFC 5988, 388 DOI 10.17487/RFC5988, October 2010, . 391 [RFC6570] Gregorio, J., Fielding, R., Hadley, M., Nottingham, M., 392 and D. Orchard, "URI Template", RFC 6570, 393 DOI 10.17487/RFC6570, March 2012, . 396 [RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 397 Protocol (HTTP/1.1): Message Syntax and Routing", 398 RFC 7230, DOI 10.17487/RFC7230, June 2014, 399 . 401 [RFC7515] Jones, M., Bradley, J., and N. Sakimura, "JSON Web 402 Signature (JWS)", RFC 7515, DOI 10.17487/RFC7515, May 403 2015, . 405 [RFC7516] Jones, M. and J. Hildebrand, "JSON Web Encryption (JWE)", 406 RFC 7516, DOI 10.17487/RFC7516, May 2015, 407 . 409 [RFC7517] Jones, M., "JSON Web Key (JWK)", RFC 7517, 410 DOI 10.17487/RFC7517, May 2015, . 413 8.2. Informative References 415 [RFC4287] Nottingham, M., Ed. and R. Sayre, Ed., "The Atom 416 Syndication Format", RFC 4287, DOI 10.17487/RFC4287, 417 December 2005, . 419 [RFC6902] Bryan, P., Ed. and M. Nottingham, Ed., "JavaScript Object 420 Notation (JSON) Patch", RFC 6902, DOI 10.17487/RFC6902, 421 April 2013, . 423 [RFC7386] Hoffman, P. and J. Snell, "JSON Merge Patch", RFC 7386, 424 DOI 10.17487/RFC7386, October 2014, . 427 [W3C.REC-html52-20171214] 428 Faulkner, S., Eicholz, A., Leithead, T., Danilo, A., and 429 S. Moon, "HTML 5.2", World Wide Web Consortium 430 Recommendation REC-html52-20171214, 14 December 2017, 431 . 433 [W3C.REC-json-ld-20140116] 434 Sporny, M., Kellogg, G., and M. Lanthaler, "JSON-LD 1.0", 435 World Wide Web Consortium Recommendation REC-json-ld- 436 20140116, 16 January 2014, . 439 [W3C.REC-xml-20081126] 440 Bray, T., Paoli, J., Sperberg-McQueen, M., Maler, E., and 441 F. Yergeau, "Extensible Markup Language (XML) 1.0 (Fifth 442 Edition)", World Wide Web Consortium Recommendation REC- 443 xml-20081126, 26 November 2008, 444 . 446 Author's Address 448 Kevin Dunglas 449 Les-Tilleuls.coop 450 5 rue Hegel 451 Lille 59000 452 France 454 Email: kevin@les-tilleuls.coop