# Security and encryption

Mailwake native push encrypts notifications on your outpost and decrypts them on the paired iPhone. This article describes the keys, encryption flow and data boundaries in Mailwake 1.0, so you can understand what you control and what passes through official services. Data processing and retention are covered by the [privacy policy](../../privacy/).

## Three data paths

Notifications, body reading and service identity use separate paths:

| Feature                   | Data path                                                       | Content processing                                                                                                               |
| ------------------------- | --------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| Native mail notifications | Mailbox → outpost → push delivery service → Apple APNs → iPhone | The outpost reads mail and encrypts notifications; the iPhone verifies, decrypts and displays them                               |
| On-demand body reading    | iPhone → your outpost → mailbox, returning along the same path  | The outpost parses the body; the App displays it in the current reading session                                                  |
| Devices and purchases     | App ↔ device and purchase service                              | Registers devices and verifies purchases; the push delivery service checks device authorization and entitlements before delivery |

Your outpost can read the mail it is authorized to access. End-to-end encryption here covers **native notification content between the outpost and the paired device**. The mailbox provider, the outpost host and decrypting device each remain within a boundary where plaintext is accessible.

## Who holds the keys

**The outpost identity key** signs content. The outpost generates a P-256 signing key locally and encrypts it with its local configuration key. Paired devices and the push delivery service receive its public key to verify the source. The identity stays with the data directory across restarts.

**The device uses two separate P-256 keys**: a signing key proves device identity and pairing consent, while a key-agreement private key decrypts notifications. The App creates keys in Secure Enclave when available and uses software keys in other runtime environments. Shared Keychain makes key records available to the App and its extensions, using `AfterFirstUnlockThisDeviceOnly` protection with iCloud Keychain synchronization disabled. Background key access requires the first device unlock after a restart.

The outpost and the push delivery service store device public keys. The device holds its decryption private key; official services and APNs do not hold that private key.

The outpost also uses `secret.key` in its data directory to encrypt sensitive configuration, including mailbox credentials, with AES-256-GCM. The database and local key together form recoverable data: [back them up](backup.md) together and protect access to the host and backups. Someone with both the database and local key can decrypt this configuration.

## How pairing establishes trust

A push-pairing QR code carries the outpost public key, the push delivery service address and environment, pairing identifier, and a single-use credential valid for five minutes. The App shows the outpost fingerprint for comparison. Use a trusted invitation from the outpost owner and check its connection information before confirming.

The device signs its consent, binding it to the outpost, device encryption key, one-time credential and expiry. The outpost verifies that proof and locks the device identity and public keys before completing registration with the push delivery service. Later notifications use this confirmed relationship to select encryption and verification keys.

A management invitation can include push pairing, but authorization remains separate: native push, configuration management and body reading each have their own permission scope. For setup, see [Connect the App](connect-app.md).

## How a notification is encrypted

For each encryption operation, the outpost generates an ephemeral P-256 key pair, a random 32-byte salt and a random 12-byte nonce. It then:

1. Performs P-256 ECDH key agreement using the ephemeral private key and the target device's public key to obtain a shared secret.
2. Derives a 256-bit content key with HKDF-SHA256. The derivation context binds the push delivery service audience, pairing ID and event ID.
3. Encrypts notification JSON with AES-256-GCM, using the same context as additional authenticated data and producing ciphertext with a 128-bit authentication tag.
4. Signs the encrypted envelope and context using the outpost P-256 signing key with SHA-256, then submits it to the push delivery service over HTTPS.
5. The push delivery service verifies the signature and envelope format and passes ciphertext to APNs. The device first verifies the signature using the outpost public key confirmed during pairing, then derives the content key with its own private key, verifies the authentication tag and decrypts.

The algorithm identifier is `P256-HKDF-SHA256-A256GCM`. Retries of the same delivery reuse its stored envelope and event identifier; new encryption operations generate fresh ephemeral keys and random values. The notification service extension handles ordinary notifications. The Widget extension handles verification-code Live Activities, which also carry signed ciphertext and bind activity identity and lifecycle fields into the encryption context.

Encrypted notifications contain the mailbox label, folder, sender, subject and received time, with an optional verification code and message reference. Full bodies use the separate path below. If signature verification or decryption fails, the device retains a safe placeholder; mail plaintext is displayed only after successful verification.

## Bodies are fetched directly over HTTPS

Opening a body sends a request to the confirmed outpost HTTPS address. The outpost checks the device credential, the owner's explicit content permission and the resource scope in the signed message reference before fetching the body and referenced inline images from the mailbox. Body reading is free; push pairing alone grants no body access.

The outpost sanitizes HTML and provides a readable text fallback. The App controls remote image loading, which can contact the sender's server, through its image-loading options. Ordinary attachments are outside this body-reading flow.

The outpost processes bodies in request memory. Responses use `Cache-Control: no-store`; the App disables HTTP caching and rejects redirects. After a successful read, the App separately saves the body and per-message image permission on this iPhone for offline reading, including after an App restart. These files use iOS file protection and are excluded from backups. Deleting or expiring a notification removes its saved body and image permission; removing an outpost also clears its saved bodies while retaining notification summaries. Remote image files remain temporary and may require another network request. Bodies travel directly from the outpost to the App, without passing through official services, and stay out of diagnostics and logs.

## What official services can see

| Participant                 | Data it can process for its role                                                                                      |
| --------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| Your outpost                | Mailbox credentials, plaintext mail, notification settings, pairing public keys and local delivery records            |
| Push delivery service       | The outpost, device and pairing identifiers; public keys; APNs tokens; encrypted envelopes; delivery times and status |
| Device and purchase service | Service identity, device and session information, purchases and entitlements, and delivery diagnostic metadata        |
| Apple APNs                  | Push tokens, routing and delivery information, generic alerts and encrypted payloads                                  |
| Your iPhone                 | Device keys, decrypted notifications and local history, and authorized message bodies                                 |

Sender, subject and verification code are inside native notification ciphertext. Intermediaries handling ciphertext can still observe delivery relationships, timing and payload sizes. Operational delivery diagnostics use identifiers, status, error codes and timestamps; mail content retains the encryption boundary above. Services also process network information needed for their roles, as described in the privacy policy.

## Local records, revocation and security limits

Pending deliveries and administrator history on the outpost have separate storage rules; local history can contain mailbox and subject summaries. The App stores decrypted notification history in its local App Group with system file data protection, configurable retention and a clear-history action. Message bodies use the separate protected cache described above.

Unpairing stops further delivery through that relationship. Revoking a content or management credential ends the corresponding access. Content already delivered and decrypted must be cleared on the device; revocation cannot recall content someone has already seen.

This design depends on the security of the outpost host, pairing invitation and device. It protects notification content in transit while a compromised outpost or unlocked device can expose plaintext. The protocol uses a long-lived device key-agreement private key: if that key is compromised, someone holding historical ciphertext may decrypt old notifications. This design therefore makes no forward-secrecy claim against compromise of the recipient's long-term private key.

Bark, Pushover and webhook channels send their respective payloads to the service you configure. The native encryption protocol above applies to the Mailwake native channel. See [Notification channels](notifications.md) for third-party data fields and preview options.
