Use of Voluntary Application Server Identification (VAPID) in JSON Meta Application Protocol (JMAP) Web Push
Extracted elements (18)
The uncompressed SEC1/X9.62 format for applicationServerKey was chosen to ensure direct compatibility with the browser Push API (W3C), so the key can be used without additional transformation. Additionally, X9.62 encoding simplifies key comparisons and is more compact than alternative formats.
Some push services require that the application server authenticate all push messages using VAPID. For these services, the client (user agent) needs the VAPID public key to pass to the push service when retrieving a new endpoint. This specification enables JMAP servers to advertise that key.
After any transitional period (or immediately for implementations without one), the server MUST destroy push subscriptions that use the old application server key.
After calling PushSubscription/set, the client MUST check whether the sessionState in the response points to a session object whose applicationServerKey matches expectations. On mismatch, the client MAY retry and MAY destroy the failed PushSubscription.
After key rotation, the server MAY continue sending push notifications for existing subscriptions using the old key during a transitional period, allowing clients time to recreate their push subscriptions.
Every time the server sends a push message to a PushSubscription URL, it MUST authenticate the POST request using the VAPID protocol (RFC 8292). This applies to both StateChange events and PushVerification notifications.
Servers supporting this specification MUST add a property called urn:ietf:params:jmap:webpush-vapid to the JMAP capabilities object. The value MUST contain the applicationServerKey field.
The client MUST monitor the JMAP session object for changes to the VAPID key and MUST recreate its push subscription when it detects such a change.
To authenticate push requests, the server MUST use a JSON Web Token (JWT) signed by the private key corresponding to the application server key that was advertised in the capabilities object at the time the PushSubscription was created.
When a server replaces its VAPID key, it MUST update the sessionState per RFC 8620, signaling clients that the session object has changed.
When destroying old-key PushSubscriptions, the server MAY issue one final StateChange push notification using the old URL and application server key, prompting the client to call PushSubscription/changes and discover the new VAPID key via the updated sessionState.
The urn:ietf:params:jmap:webpush-vapid capability object carries a single required field, applicationServerKey, which is the ECDSA public key used by the push service to authenticate the application server.
IANA has registered urn:ietf:params:jmap:webpush-vapid in the 'JMAP Capabilities' registry with intended use 'common', change controller IETF, and reference RFC 9749.
During key rotation, a race condition can arise if the server rotates its VAPID key after the client refreshes the session object but before PushSubscription/set is called. The push service will reject the subsequent PushVerification with HTTP 403, per RFC 8292 Section 4.2.
Per RFC 8620 Section 7.2, the server MUST NOT retry a rejected PushVerification request. The client is solely responsible for detecting and resolving key-rotation synchronization discrepancies by checking the applicationServerKey in the PushSubscription/set response sessionState.
The urn:ietf:params:jmap:webpush-vapid property in the JMAP capabilities object only advertises VAPID support and does not reveal sensitive information or introduce new security or privacy risks beyond those inherent to JMAP (RFC 8620) and Web Push (RFC 8030).
Key rotation defines three states: (1) active old key — server uses old key for all subscriptions; (2) transitional — server may use old key for existing subscriptions while clients recreate subscriptions with new key; (3) post-transition — server destroys all subscriptions using old key and uses only the new key. Trigger for transition is sessionState update advertising new applicationServerKey.
The applicationServerKey field is an ECDSA P-256 public key in its uncompressed form as described in SEC1 Section 2.3.3, encoded using base64url encoding (RFC 7515). The uncompressed form uses X9.62/SEC1 encoding.