Subject: Re: [Webpush] Vapid public key
From: Martin Thomson <[email-masked]>
To: jr conlin <[email-masked]>
Cc: Costin Manolache <[email-masked]>, "[email-masked]" <[email-masked]>, Peter Beverloo <[email-masked]>
Date: Fri, 25 Nov 2016 11:22:47 +1100
List-Id: Discussion of potential IETF work on a web push protocol <webpush.ietf.org>

I think that we should discuss this over on the W3C side:
Opened: https://github.com/w3c/push-api/issues/226

On 22 November 2016 at 10:53, jr conlin <[email-masked]> wrote:
> Ah, ok, my apologies.
>
> Summing up my understanding:
>
> * Yes, having the UA pass the public key string to the push server would be
> the easiest for the developer. "Ok, here's a key, you deal with it." There
> would need to be some effort on either the UA or the Push Service to verify
> that the string is a valid key set, but I believe you're specifying that. As
> I understand, a provided public key that is determined as being invalid
> whether by the UA or PS, would return an error to the application.
>
> * How that key is passed in to the UA is a point of discussion. It could be
> provided as part of the static page content provided by the subscription
> request page, it could be provided via a secondary delivery mechanism (e.g.
> included as part of a secondary script), it could be fetched by the
> application out of a well known URL (be it "/.well-known", via the app
> manifest, or "bobs-discount-public-key-goes-here.js") I'm less inclined to
> make this bit part of the formal spec so much as offering guidance for how
> app developers could do this. Various 3rd party sites, hosting sites, or
> library authors may have differing opinions based on experience and
> restrictions.
>
> * I should not read spec changes over the weekend.
>
> Does this properly sum up the changes?
>
> (Again, my apologies if I seem dense)
>
>
> On 11/21/2016 3:36 PM, Costin Manolache wrote:
>
> On Mon, Nov 21, 2016 at 9:51 AM jr conlin <[email-masked]> wrote:
>>
>> FWIW, I'm really not a fan of having an extra data path for things like
>> this. More paths mean more things that folks can screw up or not be able to
>> implement for various reasons.
>
>
>>
>> I think it's HIGHLY reasonable to ask that for a given restricted update,
>> the Application that is making the request include a public key for the
>> VAPID spec. The application could pull it from where ever, hard code it, or
>> whatever makes most sense to the Application developer team (and the
>> corresponding Subscription Update service provider).
>>
>> Things aren't exactly easy now, making them harder just means that less
>> folks will be able to do it.
>
>
> My goal was to make it easier - in particular in cases where it's easy to
> screw up. If a developer has a test key and
> a production key ( which is a good idea - you want the prod private key well
> protected, and dev/testing be done with
> a different key ), it would be easier to have a different pub key file
> rather than different .js file or extra complexity/if
>
> It is a bit more work for the UA - but not much more.
>
>>
>>
>>
>> On 11/20/2016 8:01 PM, Costin Manolache wrote:
>>
>> On Sun, Nov 20, 2016 at 5:32 PM Martin Thomson <[email-masked]>
>> wrote:
>>>
>>> On 20 November 2016 at 02:53, Costin Manolache <[email-masked]> wrote:
>>> > One more small suggestion: one of the pain points ( for me ) is the W3C
>>> > subscribe taking the
>>> > vapid pubkey as bytes instead of a string, and having to include the
>>> > key in
>>> > .js files as a constant.
>>>
>>> Your suggestion being that we define a base64url parser.  You can
>>> include the key in the form Uint8Array.from([4, 5, 6, 6, ...]);  It's
>>>
>>> bigger and you have to work itI"m a out once, but it saves shipping a
>>> converter.
>>
>>
>> Not really - the UA will need to take the uint8[] and convert it to b64 -
>> since that's what
>> the push service expects. AFAIK the UA has no use with the vapid public
>> key in current
>> protocol (except pass it along in subscribe) - we do not pass the
>> Authorization header
>> from push service to UA
>>
>>
>> I'm a bit confused here. If you use most key generation tools like
>> $ openssl ecparam -name prime256v1 -genkey -noout -out vapid_private.pem
>> $ openssl ec -in vapid_private.pem -pubout -out vapid_public.pem
>> $ grep -v "^-" vapid_public.pe
>> that dumps a b64 string the user can easily work with. Is the suggestion
>> that we ask users to convert to binary themselves? That may reduce the need
>> for base64 in the UA, but means that developers will need to add one.
>> Considering the fun that happened with "lpad" not too long ago, I'm a bit
>> concerned about the frustration that may come with that.
>
>
> My suggestion is to _not_ ask the users to convert to binary ( or array of
> decimals ) themselves - that's what the
> current W3C API requires. I'll file the bug when I return (if Peter or
> someone else doesn't beat me to it :-).
>
> And as currently defined, the browser will need to take the Uint8array and
> b64 encode it before calling the
> webpush /subscribe. I think it would be better if W3C subscribe would take a
> string, and just pass it to the push
> service with no conversions - and let the pushservice deal with it.
> It would also be more future proof.
>
>
>>
>>
>>
>>>
>>>
>>> Either way, this is probably something to take here:
>>> https://github.com/w3c/push-api/issues
>>>
>>> > Would it be possible to define a .well-known/vapid/... file where the
>>> > public
>>> > key can be saved ?
>>> > This may simplify tools, testing ( test env may use test sender keys),
>>> > etc.
>>> > One problem is that
>>> > .well-known is at root - so either have
>>> > /.well-known/vapid/ENCODED_SW_URL.pub or
>>> > have a less standard .well-known/ in the same directory with the SW.
>>>
>>> Now that we are considering removal of Crypto-Key (I'm about to send
>>> out drafts with that change), I need to work out how to push the keys
>>> along with the registration.  I don't think that using .well-known
>>> will give us the right binding to the subscription request though.
>>>
>>> Maybe I don't understand the proposal, though.  Can you walk through
>>> how a client would use this?
>>
>>
>> If client calls subscribe() - the UA will look for .well-known/vapid.pub
>> and pass it
>> in the /subscribe request to the push service.
>>
>> ... So the subscription provider will have to be able to create and
>> maintain a discrete path, the UA will need to make an extra successful data
>> call, just to provide a string that is for public consumption?
>
>
> subscribe is not a very frequent event - and a page requires plenty of
> fetches.
> The convenience to just copy a file - instead of editing a JS file - may or
> may not be worth it,
> I'm not feeling very strongly about it.
>
>
>>
>>
>>
>> If client calls subscribe( Uint8Array ) - UA will use the explicit key.
>>
>> Again, bit confused here. Granted, the UA's subscribe() function can do
>> whatever it wants once it has the public key. How the server actually enacts
>> the subscription restriction is irrelevant to both the UA and the
>> Subscription provider.
>>
>> The UA can also accept a key in several different formats by doing simple
>> tests. Likewise, how the Application acquires the key is really up to the
>> Application.
>
>
> Agreed. UA can also just pass it to push service, and let the push service
> decide how to interpret it.
>
>
>>
>> I'm seeing this more as "suggested practices" and "platform features"
>> rather than part of the specification.
>
>
>>
>> It is a bit simpler to just copy the key in a defined location - in
>> particular if you have
>> multiple environments. It is possible to do it in code too ( using the URL
>> to decide
>> which key to use ). Some people may also like the more declarative
>> approach.
>>
>> Huh, I'd argue that it may not always be possible. Some small vendor
>> platforms may not offer access to directories like "/.well-known" (e.g. if
>> you're working with classical Apache, you may be forced to root under
>> "/username/...", or some platforms may prohibit the use of leading "."
>> because of poor path management. I've had to deal with both in the past.
>>
>> Hopefully, I'm must misunderstanding the proposal again.
>
>
> My concern was to make it easier for developers to specify the public key.
> The '.well-known' was just one idea, keeping the manifest or using a
> relative path to SW, or anything else
> is fine too.
>
> Costin
>
>>
>>
>>
>>
>> Not a big deal - but I think it would be nice.
>>
>> Re. Crypto-Key: my understanding was that there are use cases for it, as a
>> way to
>> distribute keys, as discussed in the other thread. Subscribe needs some
>> header
>> ( or query param ?) to pass the authorized entity to the push service. We
>> just
>> don't need it for authorization or encrypted body.
>>
>> Costin
>>
>>
>