Norq

Web Push

Web Push (VAPID) is a built-in Norq push provider for browser-based notifications, following RFC 8030 (HTTP Push) and RFC 8292 (VAPID). It is the only Norq push provider where the endpoint is the recipient token — each browser subscription URL is unique (e.g. https://fcm.googleapis.com/wp/... for Chrome, https://updates.push.services.mozilla.com/wpush/... for Firefox).

Configuration

providers:
  webpush:
    config:
      vapidPublicKey: ${WEBPUSH_VAPID_PUBLIC_KEY}
      vapidPrivateKey: ${WEBPUSH_VAPID_PRIVATE_KEY}
      subject: mailto:ops@example.com
      # OR an HTTPS URL identifying the sender:
      # subject: https://example.com
routing:
  push: webpush
  # OR push.web specifically

All three fields are required:

  • vapidPublicKey / vapidPrivateKey — a P-256 ECDSA key pair (RFC 8292). Generate with web-push generate-vapid-keys (Node) or equivalent.
  • subject — a mailto: URL or HTTPS URL identifying the sender; required by RFC 8292 so push services can contact you.

All three accept the standard secret value forms (env var ref, file path, inline literal).

Environment-variable fallback

If providers.webpush is not declared, Norq registers Web Push when these env vars are set:

Var Required
NORQ_WEBPUSH_VAPID_PUBLIC_KEY yes
NORQ_WEBPUSH_VAPID_PRIVATE_KEY yes
NORQ_WEBPUSH_SUBJECT yes

Recipient subscription shape

Web push tokens must include the subscription’s encryption keys per RFC 8291. The recipient JSON looks like:

{
  "token": "https://fcm.googleapis.com/wp/<subscription-endpoint>",
  "platform": "web",
  "keys": {
    "p256dh": "<base64url-public-key>",
    "auth":   "<base64url-auth-secret>"
  }
}

If keys.p256dh or keys.auth is missing, the provider errors with provider/missing-vapid-keys before any HTTP call. Both keys are mandatory inputs to the ECDH payload encryption.

Capabilities

  • Channels: push (web only).
  • Batching: none. Each subscription has its own endpoint URL, so requests are inherently per-recipient.
  • Encryption: every payload is encrypted with ECDH using the subscription’s p256dh + auth keys before being sent. The recipient’s browser is the only party that can decrypt it.

CLI cannot deliver

The norq CLI binary cannot send via Web Push — VAPID requires P-256 ECDSA JWT signing plus ECDH payload encryption with HKDF, neither of which is bundled in the CLI binary. Calling norq send while routed to webpush short-circuits with provider/cli-vapid-not-supported. SDKs (Node, Python, Go, Java, Ruby) ship the encryption stack as a per-runtime crypto dependency.

Request shape

  • Body: encrypted binary blob (the Content-Encoding: aes128gcm ciphertext of the JSON push payload). The SDK performs the encryption — Norq’s prepare_send emits the plaintext payload alongside Auth::VapidWebPush { public_key, private_key, subject, sub_keys: { p256dh, auth } } and the SDK executor handles the encryption + signing.
  • Auth: Authorization: vapid t=<JWT>, k=<public-key-b64url> — the JWT’s aud claim is the push service origin and the sub claim is the configured subject.
  • Endpoint: the subscription’s own token URL. There is no shared base URL.
  • Success: 201 (Created — push service accepted). Norq does not extract a message ID from the response (push services return no body on success).
  • Retry: defaults — 429 + 5xx (500, 502, 503, 504), 2 retries, 500ms backoff. Push services return 404 / 410 when a subscription is no longer valid; treat these as terminal and remove the subscription from your store.