Skip to content

Commit bf0e832

Browse files
authored
VAPID key rotation message (#93)
1 parent 17bc111 commit bf0e832

File tree

3 files changed

+53
-12
lines changed

3 files changed

+53
-12
lines changed

content.mkd

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ A "property update" occurs when the WebDAV properties of the subscribed resource
223223
- only in property updates of the subscribed resource and its internal members (depth: `1`), or
224224
- in property updates of the subscribed resource and its members (depth: `infinity`).
225225

226-
If the subscribed resource doesn't support the content update trigger with the requested depth, the server MUST fall back to the lowest supported value instead. If the content update trigger isn't supported for the subscribed resource at all, it MUST be ignored.
226+
If the subscribed resource doesn't support the property update trigger with the requested depth, the server MUST fall back to the lowest supported value instead. If the property update trigger isn't supported for the subscribed resource at all, it MUST be ignored.
227227

228228
In case the depth is `infinity`, the limitations described in {{Section 3.3 of RFC6578}} apply: notifications about changes in members which are not supported by the `DAV:sync-collection` report may not be sent.
229229

@@ -324,11 +324,13 @@ In case of the Web Push transport, this happens over a `POST` request to the sub
324324

325325
The push message body consists of a `push-message` element, which contains information about the affected resource:
326326

327-
- a `topic` element with the push topic,
327+
- a `topic` element with the push topic (except for VAPID key rotation messages, see {{vapid-key-rotation}}),
328328
- a `content-update` element in case of a content update, and/or
329329
- a `property-update` element in case of a property update.
330330

331-
The `content-update` element SHOULD contain a `{DAV:}sync-token` element so that a client can ignore the push message when it already knows the latest state.
331+
The `content-update` element of a push message SHOULD contain a `{DAV:}sync-token` element so that a client can ignore the push message when it already knows the latest state.
332+
333+
The `property-update` element of a push message is usually empty (except for VAPID key rotation messages).
332334

333335
Example:
334336

@@ -472,7 +474,7 @@ Corresponding terminology:
472474
* (WebDAV-Push) push server ↔ (Web Push) application server
473475
* (WebDAV-Push) push client ↔ (Web Push) user agent
474476

475-
Message encryption ({{message-encryption}}) MUST be used. VAPID ({{vapid}}) SHOULD be used. (If other methods to provide a security context for Web Push become established, those can be used and necessary WebDAV properties shall be added to this document.)
477+
Message encryption ({{message-encryption}}) MUST be used. VAPID(((VAPID))) ({{vapid}}) SHOULD be used. (If other methods to provide a security context for Web Push become established, those can be used and necessary WebDAV properties shall be added to this document.)
476478

477479
A server that supports the Web Push transport MUST list the `web-push` element in the `transports` property.
478480

@@ -510,17 +512,33 @@ It contains exactly one `push-resource` element, which specifies the absolute UR
510512
A Web Push subscription is uniquely identified by its push resource.
511513

512514

513-
## VAPID {#vapid}
515+
## VAPID(((VAPID))) {#vapid}
514516

515-
VAPID {{RFC8292}} binds push subscriptions to the specific WebDAV-Push server.
517+
VAPID {{RFC8292}} binds push subscriptions to a specific WebDAV-Push server.
516518

517519
A WebDAV-Push server that supports VAPID stores a key pair. It exposes an additional transport property `vapid-public-key` within the `web-push` element, which contains the VAPID public key in uncompressed form and base64url encoded. The attribute `type="p256ecdsa"` MUST be added to allow different key types in the future. See {{push-properties}} for an example.
518520

519-
If available, the client MUST use this key to create a restricted subscription at the push service, except when it knows that the push service doesn't support VAPID.
521+
If the server provides a VAPID public key, the client MUST use that key to create a restricted subscription at the push service (except when the used push service doesn't support VAPID).
522+
523+
A client can expect the VAPID public key to be the same for all resources on the server.
524+
525+
When the server provides a VAPID public key, it MUST include a corresponding `Authorization` header when sending a push message to prove its identity to the push service.
526+
527+
### Key Rotation {#vapid-key-rotation}
528+
529+
The VAPID public key can sometimes change, either intentionally (key rotation) or for instance when the server or user data is moved to another machine. When the VAPID key has changed, a client has to create new restricted subscriptions because the old ones are bound to the old key and thus don't work anymore.
530+
531+
When a server that changes its VAPID key is able to notify clients with the old VAPID key before switching, it SHOULD send a key rotation push message to every distinct active subscription.
532+
533+
A key rotation push message is a push message that only contains a `property-update` that includes a `{DAV:}prop` property with the `transports` property like this:
534+
535+
~~~
536+
{::include xml/push-message-vapid-key.xml}
537+
~~~
520538

521-
A client can expect the VAPID public key to be the same for all resources on the server. However the VAPID public key can still sometimes change (for instance when the server or user data is moved to another machine). In that case a client has to create new restricted subscriptions because the old ones won't work anymore.
539+
A client that receives a key rotation push message MUST assume that the last known VAPID key isn't valid anymore. So in order to restore Push functionality, it has to query the new VAPID key, create a new subscription and register it again.
522540

523-
When the server provides a VAPID public key, it MUST include a corresponding `Authorization` header when sending a push message in order to prove its identity to the push service.
541+
However because it's possible that the VAPID key changes without possibility to notify the clients with the old key, clients are advised to verify the VAPID key regularly.
524542

525543

526544
## Message Encryption {#message-encryption}

xml/push-message-vapid-key.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<push-message xmlns="https://bitfire.at/webdav-push" xmlns:D="DAV:">
3+
<property-update>
4+
<D:prop>
5+
<transports />
6+
</D:prop>
7+
</property-update>
8+
</push-message>

xml/webdav-push.rng

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,10 @@
128128
<define name="push-message">
129129
<element name="push-message">
130130
<interleave>
131-
<!-- collection topic -->
132-
<ref name="prop-topic"/>
131+
<!-- collection topic (not present in VAPID key rotation message) -->
132+
<zeroOrMore>
133+
<ref name="prop-topic"/>
134+
</zeroOrMore>
133135

134136
<!-- content update -->
135137
<zeroOrMore>
@@ -143,7 +145,9 @@
143145
<!-- property update -->
144146
<zeroOrMore>
145147
<element name="property-update">
146-
<empty/>
148+
<optional>
149+
<ref name="prop-dav-prop"/>
150+
</optional>
147151
</element>
148152
</zeroOrMore>
149153
</interleave>
@@ -206,6 +210,17 @@
206210

207211
<!-- external properties (only informational) -->
208212

213+
<define name="prop-dav-prop">
214+
<element ns="DAV:" name="prop">
215+
<zeroOrMore>
216+
<element>
217+
<anyName/>
218+
<empty/>
219+
</element>
220+
</zeroOrMore>
221+
</element>
222+
</define>
223+
209224
<define name="prop-dav-depth"> <!-- defined in WebDAV (RFC 4918) -->
210225
<element ns="DAV:" name="depth">
211226
<choice>

0 commit comments

Comments
 (0)