(This document is in work and has not been submitted yet.)
WebDAV-Push is intended as a tool for WebDAV {{RFC4918}} clients to get notified about updates in collections in near time so that they can refresh their views, perform synchronization etc.
A client SHOULD NOT rely solely on WebDAV-Push, so it should also perform regular polling like when WebDAV-Push is not available. However if WebDAV-Push is available, the polling frequency can be significantly reduced.
Typical use cases:
- A mobile app synchronizes calendars/address books with device-local storage and wants to be notified on collection updates in order to re-synchronize.
- A desktop file manager shows contents of a WebDAV collection and wants to be notified on updates in order to refresh the view.
- A calendar Web app shows a CalDAV collection and wants to be notified on updates in order to refresh the view.
{::boilerplate bcp14-tagged}
1 Figure
If parts of a term are in brackets, it means that those parts may or may not be written together with the other parts. However it means the same in any case.
Push notification : push message or delivery of a push message
Push message : Actual network message that is sent from the server over a push transport to the client. Notifies the client that a specific collection (identified by its push topic) has changed.
In Web Push context, a WebDAV-Push server can send a push message (more exact, "request delivery of a push message") over the push service by POST
ing the message to the client's subscription URL.
Push service : Infrastructure that implements a specific push transport. The push service is the actual network service between WebDAV-Push server and WebDAV-Push client.
For instance, if the push transport is Web Push is a Web app, the push service would be provided by the vendor of the browser that the client runs in.
(Push) subscription (URL)
: The information that the client needs to provide to the server so that the server can send push notifications. The server can POST
a push message to that URL.
If the transport is Web Push, the term "(push) subscription (URL)" as used in this document is equivalent to the Web Push term "push resource".
(Push) topic : Character sequence that identifies a WebDAV collection for push purposes (unique per WebDAV server). A specific collection could be reachable at different URLs, but it can only have one push topic.
(Push) transport : Protocol that defines an actual push mechanism. In this document, Web Push is the only defined push transport (see {{transport-web-push}}). However, WebDAV-Push may also be used with other push transports like proprietary or yet unknown protocols. In that case, it has to be specified how to use that protocol with WebDAV-Push. A push transport typically involves a push service.
Rewrite proxy : Push services usually require authentication from their users and often consider their user to be application vendor who has control over both the server and the client.
When however the server and clients are not in control of the same entity (like it's typically the case in WebDAV context), client and server can't share the same private key to authenticate against the push service. In that case, the client vendor may need to operate a rewrite proxy that receives each push message from the WebDAV-Push server, signs it with the same private key as the client and forwards it to the push service.
Web Push : "Protocol for the delivery of real-time events to user agents", defined by {{RFC8030}}. Usually implemented in browsers (which means that major browser vendors provide their own push services), but there are also other implementations like {{UnifiedPush}}. Some parts of {{RFC8030}} (namely chapter 6 and HTTP/2 delivery between push service and client) specify implementation details that may be done by other means without changing the meaning of the RFC for WebDAV-Push servers and clients.
There are also additional standards that can be considered to belong to Web Push, especially VAPID ({{RFC8292}}) and Message Encryption ({{RFC8291}}).
WebDAV-Push : WebDAV-based protocol to notify clients about updates in collections using a push transport (vs. polling). Specified in this document.
(WebDAV-Push) client : WebDAV client that supports WebDAV-Push, for instance a CalDAV/CardDAV app on a mobile device
(WebDAV-Push) server : WebDAV server (for instance a CalDAV/CardDAV server) that implements WebDAV-Push
A WebDAV server that implements WebDAV-Push needs to
- advertise WebDAV-Push features and relevant information (service detection),
- manage subscriptions to collections and
- send push messages when a subscribed collection changes.
In order to manage subscriptions, a WebDAV server needs to
- provide a way for clients to subscribe to a collection (with transport-specific information),
- provide a way for clients to unsubscribe from collections,
- handle expired or otherwise invalid subscriptions.
Notifications about updates in collections have to be sent to all subscribed clients over the respective push transports.
The server must be prepared to handle errors. For instance, if a push transport signals that a subscription doesn't exist anymore, it must be removed and not be used again.
A WebDAV client that implements WebDAV-Push typically
- detects whether the server supports WebDAV-Push and which push transports,
- connects to a push service (which is usually not operated by the same party as the WebDAV server),
- subscribes to one or more collections on the server (providing push service-specific details),
- receives push notifications that cause some client-side action (like to refresh the view or run synchronization),
- re-subscribes to collections before the subscriptions expire,
- unsubscribes from collections when notifications are not needed anymore.
WebDAV-Push is not restricted to specific push transports and allows clients to specify which push transports they support. This allows even upcoming, yet unknown push transports to be used with WebDAV-Push.
WebDAV-Push implementations SHOULD implement at least the Web Push transport (defined in {{transport-web-push}}).
If possible, other push transports SHOULD be connected over a Web Push gateway instead of defining a new WebDAV-Push transport.
For proprietary push services, client vendors may need to provide a rewrite proxy that signs and forwards the requests to the respective proprietary service (which usually accepts only authenticated requests from the client vendor).
Push transport definitions can define extra properties and additional processing rules.
This section describes how a client can detect
- whether a collection supports WebDAV-Push,
- which push services are supported (may contain service-specific information).
To provide information about WebDAV-Push support, new collection properties are defined.
The transports
element contains push transports are supported by the server (one child element per transport). Within the scope of this document, the only supported transport is web-push
(see {{transport-web-push}}).
The topic
is a globally unique identifier for the collection. A specific collection could be reachable at different URLs, but it can only have one push topic. Because push services may be able to see push messages in clear text, the topic SHOULD NOT allow to draw conclusions about the synchronized collection. For instance, a server could use:
- a random UUID for each collection; or
- a salted hash (server-specific salt) of the canonical collection URL, encoded with base64.
Clients can use WebDAV PROPFIND
to retrieve these properties. Example:
PROPFIND https://example.com/webdav/collection/
<?xml version="1.0" encoding="utf-8" ?>
<propfind xmlns="DAV:" xmlns:P="https://bitfire.at/webdav-push">
<prop>
<P:transports/>
<P:topic/>
</prop>
</propfind>
HTTP/1.1 207 Multi-Status
<?xml version="1.0" encoding="utf-8" ?>
{::include xml/sample-propfind-multistatus.xml}
In this case, the requested collection supports WebDAV-Push in general (because it has a push topic). It supports the Web Push transport (without additional specific information).
The comment shows how support for some other (not yet defined) transport could be advertised together with additional specific information that is required to use it.
1 ACL for registering subscriptions?
To subscribe to a collection, the client sends a POST
request with Content-Type: application/xml
to the collection it wants to subscribe. The root XML element of the XML body is push-register
in the WebDAV-Push namespace (https://bitfire.at/webdav-push
) and can be used to distinguish between a WebDAV-Push and other requests.
The push-register
element contains exactly one subscription
element, which contains all information the server needs to send a push message, plus an optional expires
element that contains the requested expiration time in the IMF-fixdate
format (as defined in {{RFC9110}}).
The subscription
element specifies a subscription that shall be notified on updates and contains exactly one element with details about a specific subscription type. Within the scope of this document, only the web-push-subscription
child element is defined (see {{transport-web-push}}).
1 By now, only data updates of the collection itself and in direct members (equals Depth: 1
) are sent. Maybe it could be specified that servers can send one notification per path segment? Implications?
Allowed response codes:
- 201 if the subscription was registered and the server wants to return additional information, like encryption details that are only valid for this subscription. Details have to be specified by the particular transport definition.
- 204 if the subscription was registered
- other response code with usual HTTP/WebDAV semantics (if possible, with
DAV:error
XML body)
When a subscription is registered the first time, the server creates a URL that identifies that registration (registration URL) which can be used to remove the subscription. The server MUST send the registration URL in the Location
header.
The server MUST return a HTTP Expires
header (as defined in {{RFC9111}}) in the IMF-fixdate
format with the actual expiration date on the server, which may be shorter than the expiration requested by the client.
Example:
POST https://example.com/webdav/collection/
Content-Type: application/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
{::include xml/sample-registration.xml}
HTTP/1.1 201 Created
Location: https://example.com/webdav/subscriptions/io6Efei4ooph
Expires: Wed, 02 Oct 2024 07:28:00 GMT
Every subscription has an identifier that uniquely identifies the (push transport, push service, client) triple. For Web Push, the identifier is the push resource URI.
A server MUST NOT register a subscription with the same identifier multiple times. Instead, when a client wants to register a subscription with an identifier that is already registered for the requested collection, the server MUST update the subscription with the given details and the expiration date.
Allowed response codes:
- 201 if the registered subscription was updated and the server wants to share registration-specific details
- 204 if the registered subscription was updated
- 404 if the registration URL is unknown (or expired)
- other response code with usual HTTP/WebDAV semantics (if possible, with
DAV:error
XML body)
The server MUST return the registration URL in the Location
header.
The server MUST return a HTTP Expires
header with the actual expiration date on the server.
A client can explicitly unsubscribe from a collection by sending a DELETE
request to the previously acquired registration URL.
Allowed response codes:
- 204 if the registered subscription was removed.
- 404 if the registration URL is unknown (or expired).
- other response code with usual HTTP/WebDAV semantics (if possible, with
DAV:error
XML body)
When a subscription registration is removed, no further push messages must be sent to the subscription.
Sample request:
DELETE https://example.com/webdav/subscriptions/io6Efei4ooph
HTTP/1.1 204 Unregistered
Clients MAY specify an expiration date-time when they register a subscription.
A server SHOULD take the expiration specified by a client into consideration, but MAY impose its own (often stricter) expiration rules, for instance to keep their database clean or because the client has specified an implausible late expiration. A server MUST allow subscriptions to be valid at least three days.
Clients have to refresh their registrations regularly and before the expiration date to keep them working. They can expect that subscriptions usually stay valid until their expiration, although there may be special circumstances that cause all subscriptions to be reset, like when the server software is changed.
Expired subscriptions MUST NOT be used anymore as chances are high that doing so would cause errors.
A WebDAV-Push server MUST notify registered subscriptions when the content of a subscribed collection changes, this is when a member is added, changed or removed.
This means that a notification is sent whenever the {DAV:}sync-token
(as defined in {{RFC6578}}) or the historical {http://calendarserver.org/ns/:}GetCTag
changes.
1 Data vs. metadata, only about members or also the subscribed collection itself?
1CalDAV/CardDAV: subscribe home-set?
The push message body consists of a push-message
element, which contains a {DAV:}propstat
element with
-
an optional
{DAV:}status
element to notify the client that the collection has changed its status, and -
a
{DAV:}prop
element that- MUST contain the
topic
of the affected collection so that the client can identify it without doubt, - SHOULD contain a
{DAV:}sync-token
element (when available) to allow a client to ignore the push message when it already knows the latest state, - MUST NOT contain elements with sensitive data (unless message encryption is used).
- MUST contain the
When the {DAV:}status
element is present, it indicates a change of the status of the collection itself (and not its members). In this case, clients SHOULD check and process the relevant properties of the collection. Status code 404 or 410 is used to indicate that the collection has been removed.
1 Push notification rate limit?
1 Shall a TTL value, as used by Web Push, be recommended in general, per transport, or not at all?
1 Shall multiple enqueued (and not yet delivered) push messages for the same collection be merged to a single one (like "Replacing Push Messages" with the Topic
header in {{RFC8030}})? Maybe use a timestamp? Shall this be specified in general, per transport or not at all?
1 How often / batch / delay?
Example 1:
{::include xml/sample-push-message1.xml}
Here, the contents of the collection with topic O7M1nQ7cKkKTKsoS_j6Z3w
have changed and the new sync-token (after the change) is http://example.com/ns/sync/1234
.
Example 2:
{::include xml/sample-push-message2.xml}
Here the server notifies the client that the collection with topic O7M1nQ7cKkKTKsoS_j6Z3w
is no longer available on the server.
A WebDAV-Push server MUST ensure that invalid subscriptions (encountered when trying to sending a push notification) are removed at some time.
An invalid subscription is a subscription that push notifications can't be delivered to. Usually the push service returns an HTTP error code like 404 when it receives a notification for an invalid subscription. There may also be other conditions that render a subscription invalid, like a non-resolvable hostname or an encryption handshake error.
A server MAY use some logic like remembering the last successful delivery plus some tolerance interval to defer removal of an invalid subscription for some time. Doing so will make WebDAV-Push more reliable in case of temporary problems and avoid temporal "holes" between subscription removal and re-registration.
See RFC 3552.
Which information is shared with which party, especially public ones like the push transport? Implications? Involved parties:
- WebDAV server
- WebDAV client
- push transports / push service
Without message encryption, push transports can collect some data:
- which WebDAV server notifies which clients,
- which clients are subscribed to the same collection (because they receive the same topic in the push message),
- at which times the collection is changed,
- other metadata (IP addresses etc.)
With message encryption, every push message is different and push transports can only relate clients over metadata and heuristics, like the clients that are notified at the same time have probably subscribed the same collection.
1 How sensitive are the data, how to minimize risks
1 What happens when information leaks
1 What happens when some component is hacked
WebDAV-Push can be used with Web Push {{RFC8030}} as a transport to deliver WebDAV-Push notifications directly to compliant user agents, like Web browsers which come with their own push service infrastructure. Currently (2024), all major browsers support Web Push.
When the Web Push transport is used for WebDAV-Push,
- {{RFC8030}} defines how to generate subscriptions and send push messages,
- the WebDAV-Push server acts as Web Push application server,
- the WebDAV client (or a redirect proxy) acts as Web Push user agent.
Corresponding terminology:
- (WebDAV-Push) push subscription ↔ (Web Push) push resource
- (WebDAV-Push) push server ↔ (Web Push) application server
- (WebDAV-Push) push client (or redirect proxy) ↔ (Web Push) user agent
Usage of message encryption {{RFC8291}} and VAPID {{RFC8292}} is RECOMMENDED. If future protocol extensions become used by push services, WebDAV-Push servers should implement them as well, if applicable.
Support for the Web Push transport is indicated by the web-push
element in the transports
collection property.
A WebDAV-Push server SHOULD use the collection topic as Topic
header in push messages to replace previous notifications for the same collection.
To register a Web Push subscription, the subscription
element of the push-register
request contains exactly one web-push-subscription
.
The web-push-subscription
element represents the public information of a Web Push subscription that is shared with the WebDAV-Push server (Web Push application server).
It contains exactly one push-resource
element, which contains an absolute URI that identifies the endpoint where Web Push notifications are sent to. The push resource is used as the unique identifier for the subscription.
Example:
{::include xml/sample-web-push-subscription.xml}
The push message is delivered via POST
to the push resource, with Content-Type: application/xml; charset="UTF-8"
.
The push topic SHOULD be used to generate the Topic
header. Since RFC 8030 limits the Topic
header to 32 characters from the URL and filename-safe Base64 alphabet, it's RECOMMENDED to use a hash of the push topic that meets these requirements as the header value.
The exact algorithm to derive the Topic
header from the push topic can be chosen by the server.
The server MAY use the Urgency
header to set the priority of the push message. For instance, a CalDAV server may send push notifications for new/changed events with alarms that are scheduled within the next 15 minutes with Urgency: high
so that users receive the alarm as soon as possible. Updates that are not that time-critical for the user, for instance in slowly changing collections like a holiday calendar may be sent with Urgency: low
.
Example:
Push topic: O7M1nQ7cKkKTKsoS_j6Z3w
SHA1(push topic): 47788cfcf010ece3030175b8fa63276bbaea4862
As base64url: R3iM_PAQ7OMDAXW4-mMna7rqSGI
(Note that SHA1 doesn't serve a cryptographical purpose here and is just used to generate a fixed-length hash out of the variable-length topic.)
So push message delivery is requested with this header:
POST <push subscription URL>
Content-Type: application/xml; charset="UTF-8"
Topic: R3iM_PAQ7OMDAXW4-mMna7rqSGI
<push message body>
VAPID {{RFC8292}} SHOULD be used to restrict push subscriptions to the specific WebDAV server.
A WebDAV server which supports VAPID stores a key pair. The server exposes an additional transport property server-public-key
. It contains the VAPID public key in uncompressed form and base64url encoded. Its attribute type="p256dh"
MUST be added to allow different key types in the future.
Example service detection of a WebDAV server that supports VAPID:
<?xml version="1.0" encoding="utf-8" ?>
{::include xml/sample-propfind-multistatus-with-vapid.xml}
If available, the client SHOULD use this key to create a restricted subscription at the push service.
When the server sends a push message, it includes a corresponding Authorization
header to prove its identity.
Message encryption SHOULD be used to hide details of push messages from the push services.
Before creating the subscription, the client generates a key pair as defined in {{RFC8291}}.
When the client then registers this subscription at the server, it includes additional subscription properties:
client-public-key
– public key of the user agent's key pair in uncompressed form and base64url encoded; attributetype="p256dh"
MUST be added to allow different key types in the futureauth-secret
– authentication secret
Example for a subscription registration requesting message encryption:
{::include xml/sample-registration-with-encryption.xml}
The server uses these data to encrypt the payload and send it to the push service. The client then decrypts the payload again.
When XML element names are used without namespace in this document, they are in the WebDAV-Push namespace (https://bitfire.at/webdav-push
). All XML elements defined by this document reside in this namespace.
To reference element names in another namespace, the {ns}element
syntax is used. For instance, {DAV:}prop
means the prop
XML element in the DAV:
namespace.
The XML schema formally defines the XML elements used by this document and is expressed in {{RELAXNG}}.
{::include xml/webdav-push.rng}