Push Service Environment Config
This page is for integrators: the team that owns the product backend bridging the browser to Notify. It lists the environment variables your push service must configure, grouped by deployment environment, and what you must align with the platform team on the Notify side.
For Notify platform provisioning (VAPID keys, caller policy JSON in Key Vault, retention), see Configuration & Secrets. That page is operator-facing; this one is consumer-facing.
Every secret you configure stays on your backend. The browser never receives your push-platform token or editor token. Your backend adds Authorization and X-Source-App when forwarding to Notify.
The VAPID private key is not yours to hold — it lives only on Notify (notify-sender signs deliveries; notify-api enforces readiness). Your bridge proxies GET /api/v1/webpush/client-config and passes the public key to the browser for pushManager.subscribe().
Current workspace consumers
| Project | Status | Server envs visible in repo | Notes |
|---|---|---|---|
lumio_admin_dashboard | shipped | NOTIFY_API_URL, NOTIFY_PUSH_PLATFORM_TOKEN, NOTIFY_EDITOR_TOKEN, ADMIN_AUTH_SECRET, WEBPUSH_ALLOWED_TARGET_HOSTS | Current same-origin bridge. Uses the editor token for tenant validation and the push-platform token for browser lifecycle calls. |
online-services-front + online-services-player | in progress | push-platform token + notify host on the player proxy (online-services-player); the React client carries no Notify secrets | The browser talks to the online-services-player Node proxy, which holds the push-platform token. See Casino Integration. |
Two-party model
You configure connectivity and hold your own secrets. The platform team provisions Notify and registers your caller in the Key Vault caller-policy JSON. Values must match across both sides; env var names on your service do not have to match Notify's names.
Notify validates against NOTIFY_API_PUSH_PLATFORM_CALLERS_JSON on the platform side. Your service stores the bearer token under whatever name fits your stack (NOTIFY_PUSH_PLATFORM_TOKEN, notify.push_platform_token, a K8s Secret key, etc.). Only the token value must appear as a token field in the caller policy — the variable names differ because they belong to different services.
Variable groups
These groups apply in every environment. How you store each value (literal .env, K8s Secret, Key Vault) changes per environment — see the tables below.
| Group | What you configure | Used for |
|---|---|---|
| Connectivity | NOTIFY_API_URL | Base URL for server-to-server Notify API calls from your bridge |
| Push-platform auth | Bearer token in your secret store + fixed X-Source-App string in code | client-config, subscriptions, deactivate, events/browser, events/semantic |
| Click handoff | WEBPUSH_ALLOWED_TARGET_HOSTS | Comma-separated hostname allowlist for cross-origin /open-style redirects on your backend |
| Admin authoring (optional) | Editor bearer token in your secret store | /api/v1/tenants/, template CRUD, /webpush/send, /webpush/activity if you expose admin routes |
| Code / config (not always env) | Tenant resolution, positive player_id, same-origin bridge route paths | Identity on subscribe and semantic events |
Alignment checklist
Before going live in any environment, confirm with the platform team:
- Caller policy JSON in Key Vault includes your
caller_id, token value,allowed_routes,allowed_source_apps(yourX-Source-App), and optionaltenant_ids - Editor token value matches Notify's
INAPP_EDITOR_API_AUTH_TOKEN(only if you call editor routes) -
WEBPUSH_ALLOWED_TARGET_HOSTSon your service aligns with Notify'sNOTIFY_WEBPUSH_ALLOWED_TARGET_HOSTSwhen either side pins destination hosts -
WEB_PUSH_DRY_RUN=falseon the Notify sender workload in the target environment (otherwise pushes are skipped) - VAPID keys are provisioned on Notify (without them,
GET /api/v1/webpush/client-configreturnsPUSH_ENV_NOT_READY)
Routes your token must cover
Your push-platform caller policy must list every route your bridge calls. Minimum set for a browser lifecycle integration (Group A in the API Reference):
{
"callers": [
{
"caller_id": "your-backend",
"token": "<your-secret-token>",
"allowed_routes": [
"GET /api/v1/webpush/client-config",
"POST /api/v1/service/webpush/subscriptions",
"POST /api/v1/service/webpush/subscriptions/deactivate",
"POST /api/v1/service/webpush/events/browser",
"POST /api/v1/service/webpush/events/semantic"
],
"allowed_source_apps": ["your_source_app"],
"tenant_ids": []
}
]
}
Send X-Source-App: your_source_app on every push-platform call. The value must match an entry in allowed_source_apps.
If you also expose admin authoring routes, add the editor token and the editor routes documented in the API Reference (Group B).
Local (shared stack)
Shared local dev runs Notify on the notify_triggers_notify-local Docker network (cd notify_triggers && make local-infra && make local-up, then cd notify && make local-up). notify-api listens on http://127.0.0.1:8088.
| Variable | Example value | Where you store it | Platform must provision |
|---|---|---|---|
NOTIFY_API_URL | http://127.0.0.1:8088 | Your .env / compose | notify-api on host port 8088 |
| Push-platform token | local-dev-push-platform-token | Your .env literal | Same value in Notify's NOTIFY_API_PUSH_PLATFORM_CALLERS_JSON (see notify/.env.example) |
X-Source-App | Your app string, e.g. your_source_app | Code constant | Listed in allowed_source_apps in caller policy JSON |
| Editor token (optional) | local-dev-editor-token | Your .env literal | Matches Notify's INAPP_EDITOR_API_AUTH_TOKEN |
WEBPUSH_ALLOWED_TARGET_HOSTS | localhost,127.0.0.1 | Your .env | Optional on Notify: NOTIFY_WEBPUSH_ALLOWED_TARGET_HOSTS aligned to your click targets |
The bundled local caller policy allows only one allowed_source_apps entry. Extend NOTIFY_API_PUSH_PLATFORM_CALLERS_JSON in your local Notify config before a second backend can call browser lifecycle routes.
spark-dev1 (Kubernetes)
In-cluster push services reach Notify at the notify-svc service DNS name. Tokens are never committed to git — store them in your own K8s Secret or Key Vault and inject at deploy time.
| Variable | Example value | Where you store it | Platform must provision |
|---|---|---|---|
NOTIFY_API_URL | http://notify-svc:80 | Env in your Helm values / deployment | notify-svc release in-cluster |
| Push-platform token | <your-token> | Your K8s Secret or Key Vault | KV secret spark-dev-notify-push-platform-callers — JSON includes your caller entry |
X-Source-App | Your app string | Code constant | allowed_source_apps in that JSON |
| Editor token (optional) | <your-editor-token> | Your K8s Secret or Key Vault | KV secret spark-dev-notify-editor-token |
WEBPUSH_ALLOWED_TARGET_HOSTS | "" (empty until approved) | Env in your deployment | Optional on Notify; commented hint in platform yaml: dashboard.spark-test.newtoncelestial.com |
Platform state (dev1): NOTIFY_CHANNELS_ENABLED=WEB_PUSH,IN_APP and WEB_PUSH_DRY_RUN=false — the full web-push API path is active. VAPID and interaction-token secrets resolve from Key Vault (spark-dev-notify-vapid-public, spark-dev-notify-vapid-private, spark-dev-notify-webpush-interaction-token).
spark-prod-mexico1 (Kubernetes)
Same in-cluster connectivity pattern as dev1. Secret storage stays on your side; platform KV holds the matching caller policy and editor token.
| Variable | Example value | Where you store it | Platform must provision |
|---|---|---|---|
NOTIFY_API_URL | http://notify-svc:80 | Env in your Helm values / deployment | notify-svc release in-cluster |
| Push-platform token | <your-token> | Your K8s Secret or Key Vault | KV secret spark-mexico1-prod-notify-push-platform-callers |
X-Source-App | Your app string | Code constant | allowed_source_apps in that JSON |
| Editor token (optional) | <your-editor-token> | Your K8s Secret or Key Vault | KV secret spark-mexico1-prod-notify-editor-token |
WEBPUSH_ALLOWED_TARGET_HOSTS | "" (empty until approved) | Env in your deployment | Optional on Notify; commented hint: dashboard.prod-na-01.nwt-spark.net |
Platform state (prod-mexico1): VAPID and interaction-token KV secrets (spark-mexico1-prod-notify-vapid-public, spark-mexico1-prod-notify-vapid-private, spark-mexico1-prod-notify-webpush-interaction-token) are wired; Postgres-backed push storage on the API side is not restored yet.
Quick reference by group
| Group | Local | spark-dev1 | spark-prod-mexico1 |
|---|---|---|---|
NOTIFY_API_URL | http://127.0.0.1:8088 | http://notify-svc:80 | http://notify-svc:80 |
| Push-platform token | .env literal | Your Secret / KV | Your Secret / KV |
X-Source-App | Code constant | Code constant | Code constant |
| Editor token | .env literal (optional) | Your Secret / KV (optional) | Your Secret / KV (optional) |
WEBPUSH_ALLOWED_TARGET_HOSTS | localhost,127.0.0.1 for handoff tests | Empty until hosts approved | Empty until hosts approved |
| Web-push API ready? | Yes (local compose) | Yes | Yes |
See also
- Integration Guide — end-to-end browser + backend protocol
- Configuration & Secrets — platform-side env vars and Key Vault secret names
- API Reference — every route, header, and error code