Subject: [Webpush] Guidance requested for Cross protocol bridging

From: JR Conlin <[email-masked]>
Date: Tue, 26 May 2015 09:57:20 -0700

In order to reduce battery requirements on mobile devices, it's often
preferable to use existing messaging architectures for notification
delivery. As an example, Google Cloud Messaging (GCM) maintains a
proprietary connection between their servers and remote android devices.
It would be wasteful for applications to maintain a separate, long lived
connection back to a different server, since this connection might mean
that the device CPU or network runs more often that the native connection.

One approach is that a remote device pass a bridge descriptor object
attached to the initial subscription request which contains device
specific information. For instance, the object could contain the
preferred protocol, the local device ID required by GCM and any other
device specific information that might be required to use the
proprietary bridge network. This bridge descriptor may be common among
subscription requests.

The server then stores this information for the device. When the server
receives a new push message delivery request, it wraps the request data
to fit the proprietary bridge system requirements and sends the event to
the device. An app on the device would then process the incoming bridged
data and distribute it as if it was carried by HTTP2. The server could
return a 202 response to indicate that the message was "handed off" to a
bridge system.

It's also possible for the push system to "fall back" to HTTP2 if the
proprietary bridge fails, but there are still unresolved issues around
how the client might detect that a proprietary bridge has failed.

There are many benefits to such an approach:
* Reduced device battery requirements
* Wider device support for Push provider systems
* Push availability on legacy systems that may not yet support the Push
standard.
* "Seamless" cross-notification system support for app developers.
* etc.

There are also significant drawbacks, the largest being that it is
dependent on support by bridge providers.

Is this a reasonable approach?

---

From: Kit Cambridge <[email-masked]>
Date: Tue, 26 May 2015 18:34:54 -0700

> proprietary bridge network. This bridge descriptor may be common among

I like this approach. More concretely, the client could negotiate the
proprietary mechanism by including a header (e.g., `Push-Protocol`)
when it creates the subscription—leaving the request body reserved for
the descriptor, outside the scope of the spec. The server then replies
with a `Push-Protocol` header containing the accepted mechanism.

> return a 202 response to indicate that the message was "handed off" to a

This has implications for other app server interactions,
too—specifically around receipts, message collapsing, and TTLs.
Collapsing could be equivalent to sending a new message (which
https://github.com/unicorn-wg/webpush-protocol/pull/12 already
recommends), but the proprietary bridge might not honor the requested
TTL, or may not send feedback when the message is accepted.

We could just reinforce that acks aren't reliable to begin with, or
implementations can refuse to create receipt subscriptions when the
app server POSTs to the receipt subscribe endpoint. But definitely
something to think about.

> how the client might detect that a proprietary bridge has failed.

One possibility is that the push server stores the message if
delivery via the bridge fails. The client can then include
`Prefer: wait=0` when it GETs the subscription to pick up any missed
messages. But that still requires the client to somehow discover that the
bridge is down.

How would you handle this if you were coding against GCM (or another
bridged service) directly? Would your app (client) need to periodically
poll your app server for messages it might have missed?

---

From: jr conlin <[email-masked]>
Date: Wed, 27 May 2015 10:42:07 -0700

> something to think about.

My simplest explanation is that Notifications bear passing resemblance
to email. Granted, with SMTP, message failures are asynchronously
reported back to the user. This is not something that we currently
allow. (Likewise, I think that having the concept of an "open relay"
would probably be recognized as a horrible idea.)

Likewise, not all bridge systems will have a reporting mechanism. Some
systems may be more "Fire and Forget", where delivery may not be fully
guaranteed either.

I think the best we can offer is to report that a message has been
successfully submitted to a relay system. If our bridge system is
feeling generous, it may report failures for "closed" channels (where a
bridge system has since reported a final recipient has permanently
closed their endpoint, if that's available).
> poll your app server for messages it might have missed?

These seem to be bridge dependent, but most systems have a "registration
check" event that usually happens during app initialization. This check
returns either a token value to the app that needs to be reported back
to the remote app server, or an error. A similar approach could be
established for WebPush, where the client polls the remote server on
re-initialization to get a bridge status.

For "longer lived" apps (say, an app that may be running on a desktop or
dedicated device that may not experience daily re-initialization), it
probably should perform this function on some sort of fuzzed clock.
Obviously, there's a stampeding herd problem should these become a
significant percentage of the population, but it may be possible to
offload this check onto a secondary system that reports status and any
pending, undelivered notification events.

I am, however, quite open to better ideas.

---

From: Costin Manolache <[email-masked]>
Date: Wed, 27 May 2015 14:45:19 -0700

> that the device CPU or network runs more often that the native connection.

Strongly agreed :-)

> proprietary bridge network. This bridge descriptor may be common among

I think it would be even cleaner if GCM would return a regular webpush
subscription ( i.e. capability URL ), so the app can use the same send
protocol.

The main issue is that GCM requires a separate authentication/registration.
We have several options we're exploring to make it smoother, but
I don't think we can drop the requirement to authenticate/authorize
all senders, and this will apply to the webpush endpoint as well.

> Is this a reasonable approach?

The protocol between user agent and push service should have little impact
on
the protocol used by a server to send messages.

As long as the client gets a subscription from the UA - using the defined
W3C API -
and the server sends using the defined IETF protocol - everything should
work.

I would expect other push services to have special protocols for mobile -
less chatty, with various optimizations for unreliable connections, etc -
but
providing same features as HTTP/2.

Costin

>
> _______________________________________________
> Webpush mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/webpush
>

---

From: jr conlin <[email-masked]>
Date: Wed, 27 May 2015 16:47:02 -0700

On 5/27/2015 2:45 PM, Costin Manolache wrote:
>
>
> On Tue, May 26, 2015 at 9:57 AM, JR Conlin <[email-masked]
> <mailto:[email-masked]>> wrote:
>
Agreed. However there may be some protocols (say, one for an operator or
some legacy system that may not be able or even want to provide a modern
system), which we could use as a wrapper.
> all senders, and this will apply to the webpush endpoint as well.
Hmm... that might be a bit of an issue. I know that services such as AWS
can hold credentials in escrow and effectively be a proxy for a user
rather than a proxy for the service. The problem there is that it means
the service has to hold user credentials, and all the fun issues that
can come with that.

> The protocol between user agent and push service should have little
> impact on 
> As long as the client gets a subscription from the UA - using the
> defined W3C API - 
> and the server sends using the defined IETF protocol - everything
> should work. 
>
> less chatty, with various optimizations for unreliable connections,
> etc - but 

Ideally, yes. I'm also fine with having a "minimal set" of functions for
this. If a given app wants to take advantage of the amazing features
available using a proprietary notification system, awesome! Use that
system. No need to reproduce it. Instead, we should try to provide
enough of a system that J. Random Developer can use to write an app and
not worry about who is using it on what device or which network.

---

From: Costin Manolache <[email-masked]>
Date: Wed, 27 May 2015 21:13:07 -0700

> system), which we could use as a wrapper.

I remember the UUCP to SMTP gateways :-)

For a developer using the webpush specification - what  matters is that the
UA
returns a subscription ID, and the push services provides a HTTP endpoint
following the
standard.

I think the UA and push service developers will need to implement the
adaptation,
and I don't think the current requirements are too hard to adapt to things
like SMS
for example.

> the service has to hold user credentials, and all the fun issues that
At least in GCM - there is no 'user' involved, and I don't see why webpush
would need
user credentials.

The application instance running on the device/UA needs to have an
identifier ( subscription )
and a public key. I think expecting the sender to also have an identifier -
and a public key -
using the same mechanisms that the receiver uses - makes the protocol
symmetrical.
Both ends can use the private key to generate for example JWT tokens that
would authenticate
the subscription.

Webpush is a messaging system - SMTP and XMPP have an interesting history
and many lessons.
XMPP has authentication for both sender and receivers, and that worked
quite well.
SMTP relied on keeping the email address 'private' - similar with the
subscriptions in webpush,
and had many problems - eventually added back some complicated forms of
sender authentication.

> not worry about who is using it on what device or which network.

Agreed, and the random developer will only need to be concerned with the 2
ends
of the protocol - the W3C js API and the send part of the spec. There will
be enough
pain for him dealing with the encryption :-).

What's in the middle has more opportunities for optimization and bridging
to other
systems, without leaking into what developers just using webpush have to
deal with.

Costin

---

From: jr conlin <[email-masked]>
Date: Thu, 28 May 2015 14:14:41 -0700

On 5/27/2015 9:13 PM, Costin Manolache wrote:
>
>
> On Wed, May 27, 2015 at 4:47 PM, jr conlin <[email-masked]
>     <mailto:[email-masked]>
>     > <mailto:[email-masked] <mailto:[email-masked]>>> wrote:
>     >
>     >     It would be wasteful for applications to maintain a
>     separate, long
>     >     lived
>     >     connection back to a different server, since this connection
>     might
>     >     mean
> For a developer using the webpush specification - what  matters is
> that the UA 
> returns a subscription ID, and the push services provides a HTTP
> endpoint following the 
> standard.
>
> and I don't think the current requirements are too hard to adapt to
> things like SMS
> for example.
>
>  
>
>     >
> At least in GCM - there is no 'user' involved, and I don't see why
> webpush would need
> user credentials.
I'm not sure I follow, perhaps I wasn't clear. If GCM has an individual
authentication/registration cycle per individual, does that not imply
that any system that wishes to bridge over GCM would require it's own
authentication/registration tied to a given individual
(user/app/whatever)? If that's the case, when a system such as Push
bridges across a system like GCM, we would either have to use a common
set of credentials tied to a trusted carrier.

Maybe a user story might help.

Let's say that A is acting as a Push provider for B. who wants to use
C's Cloud Messaging (CCM). A wants to send a message to a device that's
connected via CCM.

There are two ways that this could be done.
1) B sends data to A's Push service. A bundles it and submits it to CCM
using A's credentials. On the device, an app created by A gets the
message, unbundles it, and passes the information on to B's device app.

2) B registers to use CCM and gets authentication credentials. B then
sends B credentials to A as part of the initial registration. When B
wants to send messages over CCM, A uses B's credentials (in essence,
acting as a proxy for B) which then can either go to the A client app,
or the B client app (depending on how the CCM registration process is
designed).

Scenario 1 would be preferable from a privacy and developer simplicity
point of view, but does mean that if CCM shuts down As channel, the
bridge fails for everyone.

If I understand the presentation made at Google I/O on the 28th, GCM
appears to be adopting the second approach. Is this correct?
> and a public key. I think expecting the sender to also have an
> identifier - and a public key - 
> Both ends can use the private key to generate for example JWT tokens
> that would authenticate
> the subscription.
Agreed. The content should be encrypted against the carrier in any case.
That would make handling broadcast messages tricky, since the message
would need to be decrypted by multiple keys, or each message would need
to target a given device.

Granted, distributing in plain text would be far simpler, but would
expose potentially sensitive user data.
>
> Webpush is a messaging system - SMTP and XMPP have an interesting
> history and many lessons.
> and had many problems - eventually added back some complicated forms
> of sender authentication.
>
>
>  
>
>     >
>     >
>     >
>     >
>     >     receives a new push message delivery request, it wraps the
>     request
>     >     data
>     >     * Push availability on legacy systems that may not yet
>     support the
>     >     Push
>     >     standard.
> Agreed, and the random developer will only need to be concerned with
> the 2 ends
> of the protocol - the W3C js API and the send part of the spec. There
> will be enough
> What's in the middle has more opportunities for optimization and
> bridging to other 
> systems, without leaking into what developers just using webpush have
> to deal with.
Absolutely agree! Likewise it would be fantastic if we could protect
user privacy, including as much of the "metadata" as we can.

---

From: Costin Manolache <[email-masked]>
Date: Sat, 30 May 2015 14:48:10 -0700

> appears to be adopting the second approach. Is this correct?

I'm not sure I understood the A/B/C example, let me try to describe what I
think you meant.

GCM - and I suspect other push providers - requires sender authentication.
Current webpush drafts allow this - and many other messaging protocols have
 this requirement - XMPP, even many modern SMTP servers, and I think
it is essential in any large-scale system, for many reasons ( security,
abuse,
network management, etc).

So assuming C is the push service requiring sender authentication - like
GCM, B is
a developer running an app or page on a device connected to C, and
A is another push service that needs to bridge to C.

B will use A's webpush service to send the message.

The options are:

1. A doesn't require any authentication ( open relay ). It will have to use
it's own
credentials, registered with C, and send everything with their credentials.
If there are problems with any of the apps sharing the open relay - all
traffic may be
blocked.

2. A may have some mechanism to generate different credentials for each app
- this still require
that A identifies the different applications, so I don't know how it could
work if A is an
open relay ( i.e. doesn't know who sends messages and for which app they
are ).
If A would have a way to know how to group the messages - it could manage
separate
credentials for each app.

3. A requires authentication with same scheme as C - it can just pass the
auth header to C.
This would work if A and C accept the same authentication - and it would
help if webpush defined
at least one schema, for example based on JWT tokens.

4. A requires authentication - with a different scheme than C. In this case
A would need
to generate or register a mapping between its user scheme for senders and
C, and
automatically register them with C. This would work better if webpush
defined
a registration protocol for senders - similar ( or same)  with the one
defined for registering/subscribing
 apps and UAs.

> >     >     The server then stores this information for the device. When
> the
> >     >     server
> >     >     the device. An app on the device would then process the
> incoming
> >     >     bridged
Some metadata is needed for operating the service.

Authenticating the sender doesn't need to expose more than absolutely
needed.

For example each sender could generate a key pair, and use JWT tokens to
authenticate.
I think it would be important to have at least some way to contact the
sender - almost all
problems can be resolved without resorting to completely blocking a sender.

So IMHO the minimum metadata is a public key and some way to contact - the
origin of the
domain would be great, since it can be used for some verification and
contact ( whois, postmaster).

Costin