Per-device delivery
Notifications are addressed to members, not to specific devices. When you send a notification from an app on your server, the agent seals the payload to the recipient’s atreoLINK identity public key — the same one used everywhere else for that member. atreoLINK then fans the encrypted envelope out to every device that member has paired.
What lives where
Section titled “What lives where”| Concept | Lives on |
|---|---|
| Member identity (UUID, email, identity pubkey) | atreoLINK + the agent’s ACL |
| Per-device push tokens (native APNs/FCM, WebPush subscription) | atreoLINK only |
| Per-device names (“Alice’s iPhone”, “Bob’s Pixel”) | atreoLINK + the mobile clients |
Pairing
Section titled “Pairing”When a member installs atreoLINK on a new phone (or grants notification permission to a new browser), pairing happens entirely between the client and atreoLINK:
- The client signs in and signs the registration request with the member’s identity private key.
- atreoLINK verifies the signature against the member’s pinned identity public key, then stores the push transport token (native APNs/FCM or WebPush) against that member’s record.
- From that moment on, atreoLINK fans every notification it receives for that member out to the new device too.
No state changes on the agent. The agent’s ACL already holds the member’s identity pubkey; adding a phone to that member’s account is invisible to the server.
Notification encryption
Section titled “Notification encryption”When the agent sends a notification, it seals each content field separately to the recipient’s atreoLINK identity public key using libsodium sealed-box (crypto_box_seal, X25519 + XChaCha20-Poly1305):
summary_ct = sealed_box(identity_pubkey, json({id, title, body, ...}))html_ct = sealed_box(identity_pubkey, html_string) // optionalplaintext_ct = sealed_box(identity_pubkey, plaintext_string) // optionalThese ciphertexts go to atreoLINK as part of a NotificationEnvelope. atreoLINK fans them out to every paired client of the recipient. Each client holds the member’s identity private key and decrypts locally.
Browser delivery
Section titled “Browser delivery”Browsers add a second encryption layer on top of the inner sealed-box: WebPush (RFC 8291). The browser supplies its endpoint, p256dh, and auth to atreoLINK at pairing time; atreoLINK uses those to encrypt each push to the browser’s push service (Mozilla, Apple, or Google). The Service Worker decrypts the WebPush layer first, then unwraps the inner sealed-box. atreoLINK can’t read either layer.
Unpairing
Section titled “Unpairing”Removing a device is handled entirely by atreoLINK. When a member signs out of the app on a phone, or disables notifications in the browser dashboard, atreoLINK deletes the push token row for that device. The next notification for that member skips the unpaired client.
The agent isn’t notified and doesn’t need to be — its view (members and their identity keys) hasn’t changed.
© 2026 atreoLABS. All rights reserved.
WireGuard is a registered trademark of Jason A. Donenfeld.

