Skip to content

Push: hardcoded VAPID subject uses reserved .invalid TLD; Apple returns 403 BadJwtToken #173

Description

@sccrgoalie1

Summary

The hardcoded VAPID sub claim uses a reserved .invalid TLD, which Apple's Web Push service
rejects with 403 BadJwtToken. Every attention push to an iOS subscriber fails. FCM does not
validate the sub claim, so this is invisible on the qualified Chrome/Android client.

In the v0.4.0-prealpha.1 bun archive the send call is:

send(subscription, payload, {
  subject: "mailto:security@omp-session-gateway.invalid",
  publicKey: ..., privateKey: ...,
})

.invalid is reserved by RFC 2606 and can never resolve. Apple enforces that VAPID sub is a
usable mailto: or https: contact and refuses the JWT outright.

Observed

A false → true ask transition on a Control-capable session produced no notification. The daemon
logged, at the moment of the transition:

{"level":"warn","event":"push.delivery_failed","status":403}

Repro

Same VAPID keypair, same stored subscription, same version-2 attention payload, changing only the
subject:

VAPID sub Apple response
mailto:security@omp-session-gateway.invalid (shipped) 403 {"reason":"BadJwtToken"}
https://github.com/alphastorm/omp-session-gateway 201 — notification delivered

Driven through the web-push npm package against web.push.apple.com, reading the keypair and
subscription out of push-state.json.

Suggested fix

Either make the subject configurable (a push.subject field validated as mailto:/https:), or
default it to a resolvable https: URL such as the repository URL. The existing
validateSubject check passes .invalid today because it only tests the URL scheme, not whether
the contact can exist — a .invalid host could be rejected there as well.

Scope / honesty about the environment

  • This is not a claim against the supported matrix. The host is Ubuntu 26.04 x86-64, which is
    not an advertised host, and the client is iOS Safari, which has no compatibility claim.
  • Background Web Push is documented as best-effort and outside the stable core claim, so this is
    reported as a defect in the code path, not a regression against a support promise.
  • The subject constant is platform-independent, so the diagnosis does not depend on the
    unadvertised host.

Possibly useful data point

On the same setup, an iOS 26 Safari PWA installed to the home screen registered a normal
web.push.apple.com subscription, and the session directory, View, and Control all worked against
stock OMP 18.1.21. That is one person's anecdote from an unqualified combination, not evidence for
a support claim — but it suggests this constant may be the only thing standing between the current
code and working iOS alerts.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions