Verifying what you cannot trust
Web Push in Atlas, where VAPID and RFC 8291 payload encryption keep the push service out of the notification it delivers, and a webhook receiver in the emailer that deleted its unsigned predecessor outright.
Both halves of this week’s log were about the same thing: a party I have to route through but do not control. The push service carries my notification to the phone. The webhook endpoint sits open on the internet waiting for the sender to POST to it. Neither can be removed from the design, so both have to be made to prove themselves. Of the degree’s modules, Managing Information Security was the one with genuinely new insight in it for me – mostly, I suspect, because it was the one where I had no prior intuitions to lean on. This week it stopped being case studies: I was the one naming the threat and deciding what a proportionate response looked like.
Push the service cannot read
Atlas gained Web Push across two days in mid-August, and both days were mostly about intermediaries. Web Push is, in RFC 8291’s own words, “an intermediated protocol by necessity”: my server POSTs to a push service and that service delivers to the phone. Transport encryption does not help here, because the service is the TLS endpoint – without something extra it is the first reader of every notification it delivers.
Two mechanisms, with two different jobs.
RFC 8291 message encryption keeps the service out of the content. ECDH on P-256 between a fresh ephemeral server keypair and the subscription’s p256dh key, an auth secret the user agent issued alongside the subscription, then HKDF-SHA-256 down to an AES-128-GCM key and nonce:
const prkKey = await hmacSha256(authSecret, ecdhSecret);
const keyInfo = concatBytes(ENCODER.encode('WebPush: info