How it works
Ave’s E2EE model gives each (app, identity) pair a stable, isolated encryption context. The server stores an encrypted form of your app key — it’s encrypted with the user’s passkey during the first authorization. From then on, Ave delivers the key back to you on the post-authorization redirect via URL fragment. At consent time, the Ave UI decrypts that ciphertext in the browser using the user’s master key, then places the plaintext app key in the fragment. The token and authorization-code responses do not carry the decrypted secret. For asymmetric flows (encrypting an invite or secret for another user’s identity), use identity keypairs and wrapped payloads in the JavaScript SDK.| Property | Value |
|---|---|
| Key isolation | Per-app, per-identity — different identities get different keys |
| Key stability | Same app + same identity always gets the same key context |
| Server knowledge | Zero — Ave stores only the encrypted key, never plaintext |
| Encryption algorithm | AES-GCM with a unique IV per ciphertext |
Key lifecycle
First authorization (key provisioning)
When a user authorizes your E2EE-capable app for the first time, the app generates key material client-side and encrypts it with the user’s passkey. The encrypted key is sent along with the authorization request.
Grant storage
Ave stores the encrypted key context in the user’s authorization record. The server never holds the plaintext.
Key handoff via URL fragment
After the user consents, the Ave authorization UI reads the server-stored encrypted key and decrypts it on the client side using the user’s master key. It then passes the plaintext app key to your callback as a URL fragment (
#app_key=...). The server value is never sent — the fragment contains the already-decrypted key. Parse it from the fragment before or alongside your authorization code exchange.Key import
Your app normalizes the base64 key payload (URL fragments can turn
+ into a space), decodes it, and imports it into the Web Crypto API.Fragment hygiene
The app key arrives as a URL fragment (#app_key=...). Browsers silently replace + with a space in fragment parameters, which breaks base64 decoding.
Failure handling
Key missing for an E2EE-required route
Key missing for an E2EE-required route
Block the action and prompt the user to re-authorize your app. Do not silently degrade to unencrypted storage.
Decryption fails
Decryption fails
Treat this as a key-context mismatch. Do not overwrite existing ciphertext — you could destroy data. Prompt re-authentication and re-grant.
Corrupted payload
Corrupted payload
Fail closed. Request user re-authentication rather than attempting to recover from a potentially tampered key payload.
