Encryption
atreoAGENT uses modern cryptographic primitives throughout. No traffic passes through atreoLINK in plaintext.
Transport encryption
Section titled “Transport encryption”WireGuard tunnel
Section titled “WireGuard tunnel”All client-to-server traffic is encrypted by WireGuard using:
- ChaCha20-Poly1305 for symmetric encryption.
- Curve25519 for key exchange.
- BLAKE2s for hashing.
WireGuard provides perfect forward secrecy through its Noise protocol handshake.
The reverse proxy serves all apps over HTTPS with TLS certificates from Let’s Encrypt:
- TLS 1.3 minimum (raised from 1.2). Clients connecting to the proxy must support TLS 1.3.
- Wildcard certificate for
*.<apps-hostname>(covering both the default subdomain and any active custom domain). - ACME DNS-01 challenge via atreoLINK’s DNS relay. For custom domains, the user’s own zone delegates the challenge via CNAME to
acme.<deviceId>.atreo.linkso atreoLINK never needs access to the user’s DNS. - Automatic renewal (checked daily, renewed within 30 days of expiration).
- ECDSA P-256 account key.
Notification encryption
Section titled “Notification encryption”Notifications use end-to-end encryption so that atreoLINK (the relay) never sees notification content. Each notification is encrypted to the recipient user’s atreoLINK identity public key, not to a per-device key.
Three-field sealed-box envelope
Section titled “Three-field sealed-box envelope”Each notification carries three independently encrypted fields:
| Field | Required? | Purpose |
|---|---|---|
summary | yes | Short title and body excerpt for the lockscreen banner. |
html | optional | Full HTML body, rendered in the inbox. |
plaintext | optional | Full plaintext body. |
The agent encrypts each field with libsodium’s crypto_box_seal (sealed-box, RFC 7748 X25519 plus XChaCha20-Poly1305 with an ephemeral sender keypair). The recipient’s Ed25519 identity public key is converted to its X25519 Montgomery form before sealing. Each call uses a fresh ephemeral keypair.
ct = sealed_box(recipient_x25519_pubkey, plaintext)The recipient’s identity private key, held only on their devices and browsers, decrypts. atreoLINK never sees plaintext.
Browser delivery (WebPush)
Section titled “Browser delivery (WebPush)”For browser delivery the same sealed-box ciphertext is wrapped in a WebPush layer (RFC 8291) using the browser’s p256dh and auth keys. atreoLINK signs the WebPush request with its VAPID keypair and posts it to the browser’s push service. The Service Worker decrypts the WebPush layer (transparent to JavaScript), then unwraps the inner sealed-box. atreoLINK never sees the inner plaintext at either layer.
Signature verification
Section titled “Signature verification”Device pairing
Section titled “Device pairing”During device pairing, the agent sends its Ed25519 public key fingerprint to atreoLINK. This fingerprint is verified during approval.
Client provisioning
Section titled “Client provisioning”During WireGuard client provisioning, the agent signs its response over a transcript that covers every field that ends up in the client’s wg-quick config:
transcript = SHA-256( "atreos-wg-server-v2" || nonce || client_pubkey || device_id || server_pubkey || tunnel_ip || endpoint || allowed_ips || persistent_keepalive)signature = Ed25519.Sign(agent_identity_private, transcript)The client verifies this signature against the agent’s identity public key, which it pinned at pair time.
Key storage
Section titled “Key storage”All private keys are stored in the agent’s data directory:
| File | Contents |
|---|---|
keys/ed25519.key | Device identity private key (base64). |
keys/wg_private.key | WireGuard private key (base64). |
keys/acme_account.key | ACME account private key (PEM). |
certs/<suffix>/privkey.pem | TLS private key per served suffix (PEM). |
Loaded TLS certificates are sanity-checked on startup: the agent parses the leaf and refuses to use a cert whose SAN doesn’t include *.<suffix> for the registered suffix. A swapped-on-disk cert can’t quietly take over a suffix in the registry.
User identity private keys never reach the agent or atreoLINK. They live in:
- iOS Keychain / Android Keystore on phones.
- IndexedDB on browsers (per-origin, encrypted at rest by the OS where supported).
The notification system encrypts to the public part of the user’s identity key, which the agent learns from the ACL.
Key hierarchy
Section titled “Key hierarchy”| Key | Algorithm | Purpose |
|---|---|---|
| Device identity (agent) | Ed25519 | Long-term server identity. Signs provisioning responses. Pinned in mobile after pair. |
| Owner identity (user) | Ed25519 | User’s account-level signing key. Pinned in agent at pair. |
| Member identity (user) | Ed25519 | Per-member signing key. Used to accept an invite and to authenticate wg:provision. |
| WireGuard | Curve25519 | VPN tunnel encryption and peer auth. |
| Notification content | X25519 sealed-box (libsodium) | End-to-end encryption to the recipient’s identity key. |
| ACME account | ECDSA P-256 | TLS certificate management. |
© 2026 atreoLABS. All rights reserved.
WireGuard is a registered trademark of Jason A. Donenfeld.

