End-to-end encryption
Dieser Inhalt ist noch nicht in deiner Sprache verfügbar.
End-to-end encryption (E2EE) means the server stores the content you sync only encrypted. Encryption and decryption happen on your devices; the server keeps that content as ciphertext and the keys only in wrapped form.
For the server-side architecture (endpoints, entities, workflows), see E2EE architecture.
What’s encrypted
Section titled “What’s encrypted”When E2EE is enabled, the content of these eleven record types is encrypted client-side before upload:
- Settings, templates and personas
- Providers — your AI provider configurations, API keys included
- Sessions — optimization history — and assistant chats
- Memory — your personal knowledge store
- Todos and their kanban columns
- Scheduled jobs and research sessions
What’s not encrypted, by necessity:
- Account metadata (your email, role, account creation time).
- Record metadata: per-record timestamps, IDs, owning user, entity type, sort order and column, and for personas their display and model fields.
- What the server creates or distributes itself: managed personas, client policies, plugins and your choice among them, device details and trusted certificates.
- Sync cursors and the audit log.
- The shape of your traffic — which endpoints you hit, when, from where.
- What a user hands to a background assignment — the prompt, the records they picked, and the artifact that comes back. That plane is plaintext by construction, because whatever runs the work has to read it; what bounds it is tenant isolation plus a retention window measured in hours, not encryption. It is the one route family that never travels over
/api/sync/*, and it moves nothing on its own — a user affirms each set of records by name. See the Mesh trust model.
E2EE protects content; it does not give you anonymity from the server operator.
Key hierarchy
Section titled “Key hierarchy”Three layers of keys, all 32 bytes:
| Key | What it does | How it’s stored |
|---|---|---|
| UMK — User Master Key | Wraps all DEKs. Identifies “you” cryptographically. | Generated locally; stored in DPAPI on Windows; never uploaded in plaintext |
| DEK — Data Encryption Key | One per record. Encrypts the payload. | Wrapped with UMK and stored next to the ciphertext |
| KEK — Key Encryption Key | Derived per-purpose: ECDH for device-to-device, Argon2id for recovery | Ephemeral; never stored |
Every encryption uses AES-256-GCM with AAD context binding — a string that ties a wrapped blob to its context. A blob from one context can’t be silently replayed in another:
| Purpose | Algorithm | AAD |
|---|---|---|
| Record payload | AES-GCM(DEK, plaintext) | pia-e2ee-v1:{userId}:{entityType}:{entityId} |
| DEK wrap | AES-GCM(UMK, DEK) | pia-dek-wrap-v1:{entityType}:{entityId} |
| Device-to-device wrap | AES-GCM(KEK, UMK), KEK from ECDH | pia-umk-wrap-v1:{targetDeviceId} |
| Recovery wrap | AES-GCM(KEK, UMK), KEK from Argon2id | pia-recovery-wrap-v1 |
Devices
Section titled “Devices”Each device has its own ECDH (P-256) and ECDSA (P-256) keypairs, generated locally via Windows CNG. The first device on an account self-wraps the UMK using its own keys. Each additional device must be approved from a device that’s already active:
- The new device registers as
Pendingand uploads its public keys. - An existing device sees the request and confirms (you compare a 16-character fingerprint shown on both screens —
XXXX-XXXX-XXXX-XXXX). - The existing device wraps the UMK for the new device using ECDH and signs the handover with its ECDSA key.
- The server accepts the approval only if that signature checks out against the approving device’s registered key. It keeps the signature with the wrapped UMK and marks the new device
Active. - The new device fetches the wrapped UMK, checks the signature itself, and accepts a copy another device wrapped only from a device that is still active. Then it unwraps the UMK locally.
If you don’t have an existing device handy, the recovery code is the way back in — see Recovery codes.
From server 1.4 those are the only two ways in once encryption is on. A device that registers on an encrypted
account never becomes active by registering — not even when every other device has been revoked. It stays
Pending until an active device approves it or the recovery code activates it. A device whose id is already
active but which registers with different keys — a reinstall that lost its keys, or someone who read the id
off the device list — drops back to Pending and loses its copy of the UMK; the same keys keep it active. The
first device of an account without encryption still becomes active on its own.
A pending device’s approval request belongs to the keys it registered with. If the same device id registers
again with other keys, the earlier request is void: neither an approval nor the recovery code can activate the
device through it, and the device has to ask again. Registering, approving and activating by recovery code
share a limit of 10 requests a minute per account (RateLimit__E2EEDevices__*).
Approve a device that asks again only if you set it up again yourself. After such a re-registration the device asks for approval under the name it had before. Someone holding only the account’s access token can cause exactly that request, with keys of their own under a name you trust, and approving it hands them the key.
Memory hygiene
Section titled “Memory hygiene”DEKs, KEKs, and unwrapped UMK material are zeroed in memory immediately after use on the client. Plaintext keys never touch disk except via DPAPI for the UMK at rest.