VAPID and web push (the Spur mistake)
VAPID identifies the application server to the push service with a signed JWT. The server signs with its private key. The push service verifies with the public key.
VAPID is the auth scheme that lets your application server talk to a browser push service (FCM for Chrome, Mozilla AutoPush for Firefox, Apple Push for Safari) without preregistering. You generate one ECDSA P-256 key pair, the browser gets the public key, the push service gets a signed JWT, and you can send push messages.
The flow has three parties.
- Application server: you. Holds private key.
- User agent (browser): subscribes the user. Gets public key, sends it back to you with the subscription endpoint.
- Push service: FCM, Mozilla, Apple. Routes your message to the user. Verifies your JWT signature against the public key you provide.
The JWT has three claims: aud (the push service origin), exp (expiration, max 24 hours), and sub (a mailto: link or your site URL so the push service can contact you if you abuse it). Signed with ES256 (ECDSA P-256 + SHA-256).
In code with the web-push library it is one line. webpush.setVapidDetails('mailto:you@example.com', publicKey, privateKey). The library handles the JWT, the headers, the AES-GCM encryption of the payload, and the HTTP POST. But you must understand what is happening under the hood, because that one question got me.
The payload encryption is a separate layer (RFC 8291, ECDH with the user's p256dh and auth keys). VAPID just authenticates your server to the push service. The actual notification content is encrypted end-to-end so the push service cannot read it.
Learn more
- Docs
- Docs
- Repoweb-push libraryGitHub