Some checks failed
Code scanning / CodeQL (push) Failing after 15s
Zulip production suite / Ubuntu 22.04 production build (push) Failing after 26s
Zulip production suite / Debian 12 production install with custom db name and user (push) Has been skipped
Zulip production suite / Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga (push) Has been skipped
Zulip production suite / Ubuntu 24.04 production install (push) Has been skipped
Zulip production suite / Ubuntu 26.04 production install (push) Has been skipped
Zulip production suite / Debian 13 production install (push) Has been skipped
Zulip production suite / 7.0 Version Upgrade (push) Has been skipped
Zulip production suite / 8.0 Version Upgrade (push) Has been skipped
Zulip production suite / 6.0 Version Upgrade (push) Has been skipped
Zulip production suite / 10.0 Version Upgrade (push) Has been skipped
Zulip production suite / 9.0 Version Upgrade (push) Has been skipped
Zulip production suite / 12.0 Version Upgrade (push) Has been skipped
Zulip production suite / 11.0 Version Upgrade (push) Has been skipped
GitHub Actions Security Analysis with zizmor / zizmor (push) Failing after 3s
Zulip CI / Debian 12 (Python 3.11, backend + documentation) (push) Failing after 26s
Zulip CI / Ubuntu 22.04 (Python 3.10, backend + frontend) (push) Failing after 3s
Zulip CI / Ubuntu 24.04 (Python 3.12, backend) (push) Failing after 25s
Zulip CI / Ubuntu 26.04 (Python 3.14, backend) (push) Failing after 25s
Zulip CI / Debian 13 (Python 3.13, backend) (push) Failing after 28s
Zulip production suite / Required jobs (push) Has been cancelled
Zulip CI / Required jobs (push) Has been cancelled
API Documentation Update Check / check-feature-level-updated (push) Has been cancelled
API Documentation Update Check / notify-if-api-docs-changed (push) Has been cancelled
548 lines
23 KiB
Markdown
548 lines
23 KiB
Markdown
# Mobile push notification service
|
||
|
||
Zulip's iOS and Android [mobile apps](https://zulip.com/apps/) support
|
||
receiving push notifications from Zulip servers to notify users when
|
||
new messages have arrived. This is an important feature for having a
|
||
great mobile app experience.
|
||
|
||
Google's and Apple's security model for mobile push notifications does not allow
|
||
self-hosted Zulip servers to directly send mobile notifications to the Zulip
|
||
mobile apps. The Zulip Mobile Push Notification Service solves this problem by
|
||
forwarding E2EE mobile push notifications generated by your server to the Zulip
|
||
mobile apps. With Zulip Server 12.0+ and an up-to-date Zulip mobile app, the
|
||
notifications are encrypted end-to-end from your server to your mobile device.
|
||
|
||
## Signing up
|
||
|
||
:::{important}
|
||
|
||
The Zulip Server 10.0+ [installer](install.md#step-2-install-zulip)
|
||
includes a `--push-notifications` flag that automates this
|
||
registration process.
|
||
|
||
These instructions apply to Zulip 9.0+. If you are running an older
|
||
version of Zulip ([check](https://zulip.com/help/view-zulip-version)
|
||
if you are unsure), see the [Zulip 8.x
|
||
documentation](https://zulip.readthedocs.io/en/8.4/production/mobile-push-notifications.html).
|
||
:::
|
||
|
||
You can enable the mobile push notification service for your Zulip
|
||
server as follows:
|
||
|
||
1. Make sure your server has outgoing HTTPS access to the public Internet. If
|
||
that is restricted by a proxy, you will need to [configure Zulip to use your
|
||
outgoing HTTP proxy](deployment.md#customizing-the-outgoing-http-proxy)
|
||
first.
|
||
|
||
1. Make sure that the `ZULIP_ADMINISTRATOR` setting in your
|
||
`/etc/zulip/settings.py` file is a real email address which you
|
||
monitor. If the Mobile Push Notification Service needs to contact
|
||
you regarding your server, and will use this email address. [See
|
||
below](#updating-your-servers-registration) for instructions if
|
||
this contact needs to be updated later.
|
||
|
||
1. Set `ZULIP_SERVICE_PUSH_NOTIFICATIONS = True` in your
|
||
`/etc/zulip/settings.py` file. Simply uncomment the appropriate line [in
|
||
settings.py][update-settings-docs] by deleting the initial `# `.
|
||
|
||
1. Decide whether to share usage statistics with the Zulip team.
|
||
|
||
By default, Zulip installations using the Mobile Push Notification Service
|
||
submit additional usage statistics that help Zulip's maintainers allocate
|
||
resources towards supporting self-hosted installations
|
||
([details](#uploading-usage-statistics)). You can disable submitting usage
|
||
statistics now or at any time by setting
|
||
`ZULIP_SERVICE_SUBMIT_USAGE_STATISTICS=False` in `/etc/zulip/settings.py`
|
||
(uncomment the appropriate line).
|
||
|
||
Note that all systems using the service upload [basic
|
||
metadata](#uploading-basic-metadata) about the organizations hosted
|
||
by the installation.
|
||
|
||
[update-settings-docs]: ../production/upgrade.md#updating-settingspy-inline-documentation
|
||
|
||
1. [Restart your Zulip server](settings.md#changing-server-settings) so that
|
||
your configuration changes take effect.
|
||
|
||
1. Run the registration command. If you installed Zulip directly on the server
|
||
(without Docker), run as root:
|
||
|
||
```
|
||
su zulip -c '/home/zulip/deployments/current/manage.py register_server'
|
||
```
|
||
|
||
Or if you're {doc}`using Docker <docker:index>`, run:
|
||
|
||
```
|
||
cd docker-zulip
|
||
./manage.py register_server
|
||
```
|
||
|
||
This command will print the registration data it would send to the Mobile
|
||
Push Notification Service, ask you to accept the terms of service, and if
|
||
you accept, register your server. If you have trouble, [contact Zulip
|
||
support](https://zulip.com/help/contact-support) with the output of this
|
||
command.
|
||
|
||
1. Organizations with more than 10 users must upgrade their
|
||
[plan](https://zulip.com/plans/) in order to access the Mobile Push
|
||
Notification Service. See [plan management](#plan-management) for details.
|
||
|
||
1. If you or your users have already set up the Zulip mobile app, you'll each
|
||
need to log out of the mobile app, and log back in again in order to start
|
||
getting push notifications.
|
||
|
||
Congratulations! You've successfully set up the service. You can now test mobile
|
||
push notifications by following [these
|
||
instructions](https://zulip.com/help/mobile-notifications#testing-mobile-notifications).
|
||
|
||
## Plan management
|
||
|
||
To access the Mobile Push Notification Service, organizations with more than 10
|
||
users must upgrade to a paid [plan](https://zulip.com/plans/#self-hosted), or
|
||
the free Community plan (if
|
||
[eligible](https://zulip.com/help/self-hosted-billing#free-community-plan)).
|
||
While upgrading your Zulip server to version 8.0+ makes it more convenient to
|
||
manage your plan, the same plans are offered for all Zulip versions.
|
||
|
||
### Plan management for a Zulip organization
|
||
|
||
On a self-hosted Zulip server running Zulip 8.0+, [organization
|
||
owners](https://zulip.com/help/user-roles) and billing administrators
|
||
can conveniently access plan management from the Zulip app. See [help center
|
||
documentation](https://zulip.com/help/self-hosted-billing) for detailed
|
||
instructions.
|
||
|
||
#### Configure who can manage plans and billing
|
||
|
||
::::{tab-set}
|
||
|
||
:::{tab-item} Zulip Server 10.0+
|
||
|
||
Follow [these
|
||
instructions](https://zulip.com/help/self-hosted-billing#configure-who-can-manage-plans-and-billing)
|
||
to configure who can manage plans and billing.
|
||
|
||
:::
|
||
|
||
:::{tab-item} Older versions
|
||
|
||
You can add billing administrators using the `change_user_role` [management
|
||
command][management-commands], passing [the organization's
|
||
`string_id`][accessing-string-id], and the email address of the Zulip user who
|
||
should be added as a billing administrator.
|
||
|
||
```
|
||
/home/zulip/deployments/current/manage.py change_user_role -r '' username@example.com is_billing_admin
|
||
```
|
||
|
||
You can remove a user's billing administrator permissions with the `--revoke`
|
||
option:
|
||
|
||
```
|
||
/home/zulip/deployments/current/manage.py change_user_role --revoke -r '' username@example.com is_billing_admin
|
||
```
|
||
|
||
:::
|
||
|
||
::::
|
||
|
||
[management-commands]: ../production/management-commands.md
|
||
[accessing-string-id]: https://zulip.readthedocs.io/en/stable/production/management-commands.html#accessing-an-organization-s-string-id
|
||
|
||
### Plan management for an entire Zulip server
|
||
|
||
Servers running Zulip releases older than Zulip 8.0 can start the plan
|
||
management log in process at
|
||
<https://selfhosting.zulip.com/serverlogin/>. This option is also
|
||
available for Zulip 8.0+ servers, and makes it possible to use a
|
||
single plan for multiple organizations on one installation. See [help
|
||
center documentation](https://zulip.com/help/self-hosted-billing) for
|
||
detailed log in instructions.
|
||
|
||
You will use your server's `zulip_org_id` and `zulip_org_key` as the username
|
||
and password to access plan management. You can obtain these from
|
||
`/etc/zulip/zulip-secrets.conf` on your Zulip server, or via the following
|
||
commands:
|
||
|
||
```
|
||
/home/zulip/deployments/current/scripts/get-django-setting ZULIP_ORG_ID
|
||
/home/zulip/deployments/current/scripts/get-django-setting ZULIP_ORG_KEY
|
||
```
|
||
|
||
## Why a push notification service is necessary
|
||
|
||
Both Google's and Apple's push notification services have a security
|
||
model that does not support mutually untrusted self-hosted servers
|
||
sending push notifications to the same app. In particular, when an
|
||
app is published to their respective app stores, one must compile into
|
||
the app a secret corresponding to the server that will be able to
|
||
publish push notifications for the app. This means that it is
|
||
impossible for a single app in their stores to receive push
|
||
notifications from multiple, mutually untrusted, servers.
|
||
|
||
Zulip's solution to this problem is to provide a central push
|
||
notification forwarding service, which allows registered Zulip servers
|
||
to send push notifications to the Zulip app indirectly (through the
|
||
forwarding service).
|
||
|
||
## Security and privacy
|
||
|
||
:::{note}
|
||
Use of the push notification bouncer is subject to the Zulip Cloud [Terms of
|
||
Service](https://zulip.com/policies/terms), [Privacy
|
||
Policy](https://zulip.com/policies/privacy) and [Rules of
|
||
Use](https://zulip.com/policies/rules). By using push notifications, you agree
|
||
to these terms.
|
||
:::
|
||
|
||
Zulip Server 12.0+ uses end-to-end encryption (E2EE) when sending push
|
||
notifications to the Zulip mobile app. E2EE ensures that message
|
||
**content** and **metadata** (including the sender's name, and the
|
||
recipient's name or channel and topic where the message was sent) are
|
||
not visible to Apple, Google, or Zulip's [Mobile Push Notification
|
||
Service](https://zulip.readthedocs.io/en/stable/production/mobile-push-notifications.html).
|
||
|
||
The Zulip server encrypts the contents of each notification
|
||
with a per-device symmetric key shared between the Zulip server and the
|
||
user's mobile app. The Push Notification Service forwards the encrypted
|
||
payload without being able to decrypt it.
|
||
|
||
If either the Zulip Server or the mobile app is a version predating
|
||
the 12.0 release (April 2026) that does not support the E2EE protocol,
|
||
the [legacy push notifications protocol](#legacy-protocol) will be
|
||
used. Organization administrators can
|
||
[require](https://zulip.com/help/mobile-notifications#require-end-to-end-encryption-for-mobile-push-notifications)
|
||
E2EE for message content in mobile push notifications.
|
||
|
||
If you have any questions about the security model, [contact Zulip
|
||
support](https://zulip.com/help/contact-support).
|
||
|
||
### What Apple, Google, and the Push Notification Service see
|
||
|
||
For each notification, the Push Notification Service receives and forwards to
|
||
Apple or Google:
|
||
|
||
- The opaque APNs or FCM token identifying the target device (known to the
|
||
service from registration, and never seen in plaintext by the Zulip server).
|
||
- An identifier selected by the mobile app (`push_key_id`) that the mobile app
|
||
uses to select the correct decryption key. This identifier is opaque to
|
||
the service.
|
||
- The encrypted notification payload (an XSalsa20+Poly1305
|
||
ciphertext), forwarded to Apple or Google inside the push payload.
|
||
- The delivery priority (higher for a new message, lower for a notification
|
||
removal).
|
||
|
||
The notification contents — including the message, sender, recipient,
|
||
channel, and topic — are inside an encrypted ciphertext that Apple,
|
||
Google, and the service cannot decrypt.
|
||
|
||
All network requests — from Zulip servers to the Push Notification Service,
|
||
and from the Push Notification Service to Apple and Google — are encrypted
|
||
over the wire with SSL/TLS.
|
||
|
||
### What the Push Notification Service stores
|
||
|
||
The Push Notification Service stores the following metadata for as long as
|
||
a device's registration is active:
|
||
|
||
- The APNs and FCM tokens needed to deliver push notifications to iOS and
|
||
Android devices, one per device registered with your Zulip server.
|
||
- [Basic organization metadata](#uploading-basic-metadata),
|
||
[optional usage statistics](#uploading-usage-statistics), and aggregate
|
||
statistics about how many push notifications are sent by each server.
|
||
|
||
### What the Zulip server sees
|
||
|
||
The Zulip server is the source of every notification it sends, and
|
||
holds the symmetric key used to encrypt each notification for
|
||
delivery.
|
||
|
||
E2EE makes notification contents opaque to Apple, Google, and the Push
|
||
Notification Service, but it does **not** protect against a compromised or
|
||
malicious Zulip server. Learn about [Zulip's approach to
|
||
security](https://zulip.com/security/), and [keep your server
|
||
safe](./securing-your-zulip-server.md).
|
||
|
||
### Limitations
|
||
|
||
The E2EE protocol has the following known limitations:
|
||
|
||
- **Incomplete forward secrecy.** A device's symmetric key persists until the
|
||
mobile app rotates it (generally every 30 days), and is stored by both the
|
||
mobile app and the Zulip server. An attacker who obtains both a historical
|
||
capture of encrypted push payloads and the device's current key — for example,
|
||
by compromising the mobile device or the Zulip server — can decrypt the
|
||
notifications captured since the key was last rotated.
|
||
|
||
- **Metadata side channels.** The Push Notification Service, and
|
||
indirectly Apple and Google, can observe the timing, delivery priority,
|
||
and size of each push notification. These side channels can reveal
|
||
coarse patterns of activity even though message contents are encrypted.
|
||
|
||
### Cryptography
|
||
|
||
The E2EE protocol encrypts each notification payload with libsodium's
|
||
`crypto_secretbox_easy` (XSalsa20-Poly1305 authenticated encryption) using
|
||
a per-device 256-bit symmetric key and a fresh 192-bit random nonce per
|
||
notification. Initial registration of a device with the Push Notification
|
||
Service uses libsodium's `crypto_box_seal` (Curve25519 + XSalsa20-Poly1305)
|
||
so that the Zulip server can forward the device's APNs/FCM token to the
|
||
bouncer without learning the token itself. A one-byte algorithm prefix on
|
||
each symmetric key reserves space for future cipher migrations.
|
||
|
||
The code for the push notification forwarding service is 100% open source,
|
||
and is available as part of the [Zulip server project on
|
||
GitHub](https://github.com/zulip/zulip) (specifically,
|
||
[here](https://github.com/zulip/zulip/tree/main/zilencer)).
|
||
|
||
### Uploading basic metadata
|
||
|
||
All Zulip installations running Zulip 8.0 or greater that are
|
||
registered for the Mobile Push Notification Service regularly upload
|
||
to the service basic metadata about the organizations hosted by the
|
||
installation. (Older Zulip servers upload these metadata only if
|
||
[uploading usage statistics](#uploading-usage-statistics) is enabled).
|
||
|
||
Uploaded metadata consists of, for each organization hosted by the
|
||
installation:
|
||
|
||
- A subset of the basic metadata returned by the unauthenticated [`GET
|
||
/server_settings` API
|
||
endpoint](https://zulip.com/api/get-server-settings).
|
||
|
||
The purpose of that API endpoint is to serve the minimal data
|
||
needed by the Zulip mobile apps in order to:
|
||
|
||
- Verify that a given URL is indeed a valid Zulip server URL
|
||
- Present a correct login form, offering only the supported features
|
||
and authentication methods for that organization and Zulip server
|
||
version.
|
||
|
||
Most of the metadata it returns is necessarily displayed to anyone
|
||
with network access to the Zulip server on the login and signup
|
||
pages for your Zulip organization as well.
|
||
|
||
(Some fields returned by this endpoint, like the organization icon
|
||
and description, are not included in uploaded metadata.)
|
||
|
||
- The [organization type](https://zulip.com/help/organization-type)
|
||
and creation date.
|
||
- The number of user accounts with each role.
|
||
|
||
Our use of uploaded metadata is governed by the same [Terms of
|
||
Service](https://zulip.com/policies/terms) and [Privacy
|
||
Policy](https://zulip.com/policies/privacy) that covers the Mobile
|
||
Push Notification Service itself.
|
||
|
||
### Uploading usage statistics
|
||
|
||
By default, Zulip installations that register for the Mobile Push
|
||
Notification Service upload the following usage statistics. You can
|
||
disable these uploads any time by setting
|
||
`ZULIP_SERVICE_SUBMIT_USAGE_STATISTICS=False` in `/etc/zulip/settings.py`.
|
||
|
||
- Totals for messages sent and read with subtotals for various
|
||
combinations of clients and integrations.
|
||
- Totals for active users under a few definitions (1day, 7day, 15day)
|
||
and related statistics.
|
||
|
||
Some of the graphs on your server's [usage statistics
|
||
page](https://zulip.com/help/analytics) can be generated from these
|
||
statistics.
|
||
|
||
When enabled, usage statistics are submitted via an hourly cron
|
||
job. If you'd like to access plan management immediately after
|
||
enabling `SUBMIT_USAGE_STATISTICS=True` (the legacy form of this setting)
|
||
on a pre-8.0 Zulip server, you can run the analytics job manually via:
|
||
|
||
```
|
||
/home/zulip/deployments/current/manage.py update_analytics_counts
|
||
```
|
||
|
||
Our use of uploaded usage statistics is governed by the same [Terms of
|
||
Service](https://zulip.com/policies/terms) and [Privacy
|
||
Policy](https://zulip.com/policies/privacy) that covers the Mobile
|
||
Push Notification Service itself.
|
||
|
||
## Rate limits
|
||
|
||
The Mobile Push Notification Service API has a very high default rate
|
||
limit of 1000 requests per minute. A Zulip server makes requests to
|
||
this API every time it sends a push notification, which is fairly
|
||
frequent, but we believe it to be unlikely that a self-hosted
|
||
installation will hit this limit.
|
||
|
||
This limit is primarily intended to protect the service against DoS
|
||
attacks (intentional or otherwise). If you hit this limit or you
|
||
anticipate that your server will require sending more push
|
||
notifications than the limit permits, please [contact
|
||
support](https://zulip.com/help/contact-support).
|
||
|
||
## Updating your server's registration
|
||
|
||
Your server's registration includes the server's hostname and contact
|
||
email address (from `EXTERNAL_HOST` and `ZULIP_ADMINISTRATOR` in
|
||
`/etc/zulip/settings.py`, aka the `--hostname` and `--email` options
|
||
in the installer). You can update your server's registration data by
|
||
running `manage.py register_server` again.
|
||
|
||
If you'd like to rotate your server's API key for this service
|
||
(`zulip_org_key`), you need to use
|
||
`manage.py register_server --rotate-key` option; it will automatically
|
||
generate a new `zulip_org_key` and store that new key in
|
||
`/etc/zulip/zulip-secrets.conf`.
|
||
|
||
## Moving your registration to a new server
|
||
|
||
When migrating your Zulip deployment to a new machine, you will likely want to
|
||
retain your original registration and successfully transfer it. This is
|
||
especially important if you have an active plan for the Mobile Push
|
||
Notification Service.
|
||
|
||
The best way to preserve your registration when moving to a new server is to
|
||
copy over the credentials from the old server. These credentials are stored in
|
||
the `/etc/zulip/zulip-secrets.conf` file, specifically in the `zulip_org_id`
|
||
and `zulip_org_key` fields. After installing Zulip on the new machine, ensure
|
||
that `zulip_org_id` and `zulip_org_key` are set to the same values as on the
|
||
old server.
|
||
|
||
If you used the [official backup tool](export-and-import.md#backups)
|
||
to restore your Zulip deployment on the new machine, it will have
|
||
automatically transferred all secrets, including the registration
|
||
credentials, correctly.
|
||
|
||
### Transferring your registration if you lost the original credentials
|
||
|
||
If you have lost your original credentials, you can still transfer your Zulip
|
||
registration to a new server by following these steps:
|
||
|
||
1. Ensure Zulip is installed and accessible:
|
||
|
||
- Install Zulip on the new machine and ensure it is fully operational.
|
||
- The server must be accessible on the hostname associated with the original
|
||
registration, with properly configured SSL certificates.
|
||
- This process **will not work** if your Zulip server is on a local network
|
||
or otherwise unreachable from the internet by our Mobile Push Notification
|
||
Service. If that’s the case, contact
|
||
[support@zulip.com](mailto:support@zulip.com) for assistance.
|
||
|
||
1. Run the below command to transfer your registration to the new server. This will
|
||
execute a verification flow to prove to our Mobile Push Notification Service that
|
||
you control the hostname and upon success, re-generate the credentials for
|
||
using the registration and write them to the `/etc/zulip/zulip-secrets.conf` file.
|
||
|
||
```bash
|
||
/home/zulip/deployments/current/manage.py register_server --registration-transfer
|
||
```
|
||
|
||
Note that the `zulip_org_key` value changes in the process, and therefore if you
|
||
still have an old server running using the service, it will lose access upon
|
||
execution of this command.
|
||
|
||
1. Apply the changes by restarting the server:
|
||
|
||
```bash
|
||
/home/zulip/deployments/current/scripts/restart-server
|
||
```
|
||
|
||
Finally, [verify][verify-push-notifications] that push
|
||
notifications are working correctly. If you encounter further
|
||
issues, contact [support@zulip.com](mailto:support@zulip.com).
|
||
|
||
1. If you store `/etc/zulip/zulip-secrets.conf` secrets externally in
|
||
an external configuration management tool (Ansible, etc.), or
|
||
[backups](export-and-import.md#backups), this is a good time to
|
||
update that configuration.
|
||
|
||
[verify-push-notifications]: https://zulip.com/help/mobile-notifications#testing-mobile-notifications
|
||
|
||
## Deactivating your server's registration
|
||
|
||
If you are deleting your Zulip server or otherwise no longer want to
|
||
use the Mobile Push Notification Service, you can deactivate your server's
|
||
registration.
|
||
|
||
1. [Cancel any paid
|
||
plans](https://zulip.com/help/self-hosted-billing#cancel-paid-plan)
|
||
associated with your server.
|
||
|
||
1. Run the deregistration command. If you installed Zulip directly on
|
||
the server (without Docker), run as root:
|
||
|
||
```
|
||
su zulip -c '/home/zulip/deployments/current/manage.py register_server --deactivate'
|
||
```
|
||
|
||
Or if you're {doc}`using Docker <docker:index>`, run:
|
||
|
||
```
|
||
cd docker-zulip
|
||
./manage.py register_server --deactivate
|
||
```
|
||
|
||
1. Comment out the
|
||
`ZULIP_SERVICE_PUSH_NOTIFICATIONS = True` line
|
||
in your `/etc/zulip/settings.py` file (i.e., add `# ` at the
|
||
start of the line), and [restart your Zulip
|
||
server](settings.md#changing-server-settings).
|
||
|
||
If you ever need to reactivate your server's registration, [contact Zulip
|
||
support](https://zulip.com/help/contact-support).
|
||
|
||
### Pausing use of the Mobile Push Notification Service
|
||
|
||
You can temporarily stop using the Mobile Push Notification Service. Comment out
|
||
the `PUSH_NOTIFICATION_BOUNCER_URL = 'https://push.zulipchat.com'` line in your
|
||
`/etc/zulip/settings.py` file (i.e., add `# ` at the start of the line), and
|
||
[restart your Zulip server](settings.md#changing-server-settings). This approach makes it
|
||
easy to start using the service again by uncommenting the same line.
|
||
|
||
### Legacy protocol
|
||
|
||
Zulip Servers running 12.0+ sending notifications to a modern mobile
|
||
app version will always use the E2EE protocol. If either the Zulip
|
||
Server or the mobile app is a version predating the 12.0 release
|
||
(April 2026) that does not support the E2EE protocol, the legacy
|
||
non-E2EE protocol will be used.
|
||
|
||
The central design goal of the legacy Push Notification Service
|
||
service was to avoid any message content being stored or logged by the
|
||
service, even in error cases.
|
||
|
||
- The Push Notification Service only stores the necessary metadata for
|
||
delivering the notifications to the appropriate devices and
|
||
otherwise operating the service:
|
||
- The APNS/FCM tokens needed to securely send mobile push
|
||
notifications to iOS and Android devices, one per device
|
||
registered to be notified by your Zulip server.
|
||
- User ID numbers generated by your Zulip server, needed to route
|
||
a given notification to the appropriate set of mobile devices.
|
||
These user ID numbers are opaque to the Push Notification
|
||
Service and Kandra Labs.
|
||
- [Basic organization metadata](#uploading-basic-metadata),
|
||
[optional usage statistics](#uploading-usage-statistics), and
|
||
aggregate statistics about how many push notifications are sent by
|
||
each customer.
|
||
- The Push Notification Service receives (but does not store) the
|
||
contents of individual mobile push notifications:
|
||
|
||
- The numeric message ID generated by your Zulip server.
|
||
- Metadata on the message's sender (name and avatar URL).
|
||
- Metadata on the message's recipient (channel name + ID, topic,
|
||
direct message recipients, etc.).
|
||
- A timestamp.
|
||
- The message's content.
|
||
|
||
Organization administrators can [require end-to-end encryption for
|
||
push notifications][require-e2ee]. When this setting is enabled,
|
||
legacy push notifications are not sent; only clients that support
|
||
E2EE push notifications will receive push notifications.
|
||
|
||
[require-e2ee]: https://zulip.com/help/mobile-notifications#require-end-to-end-encryption-for-mobile-push-notifications
|
||
|
||
- All of the network requests (both from Zulip servers to the Push
|
||
Notification Service and from the Push Notification Service to the
|
||
relevant Google and Apple services) are encrypted over the wire with
|
||
SSL/TLS.
|