Ave can deliver a per-app, per-identity encryption key for E2EE-capable apps.
Two mechanisms (do not confuse them)
| Mechanism | What gets decrypted | Where the secret appears |
|---|
App E2EE key (app_key) | The per-app symmetric key ciphertext Ave stored for this grant | URL #fragment after consent — see below |
| Identity wrapped payloads | Arbitrary bytes for another user | Encrypted with their published public key; ciphertext usually lives in your app — see identity keys |
#app_key is delivered in the fragment because only the browser on aveid.net can unlock the master key — not your redirect page alone. Wrapped invite ciphertext is stored in your app; the recipient unwraps with decryptWrappedPayload in the browser after unlocking the master key. Use the E2EE app key for ongoing storage after handoff — it is not the same as wrapped payload crypto. Details: Identity keys.
How key handoff works
- App is marked
supportsE2ee
- During the consent step, the Ave authorization UI decrypts the server-stored encrypted key using the user’s master key
- The plaintext app key is passed to your callback as a URL fragment (
#app_key=...) — never in the JSON token response
- Parse and clear the fragment before or alongside the authorization code exchange
Storage model
- Key is identity-specific
- Same identity gets same app key across logins
- Different identities must map to separate encrypted data domains
URL-fragment parsing gotcha
When parsing fragment with URLSearchParams, + may become space. Normalize before decoding.
const hashParams = new URLSearchParams(window.location.hash.slice(1));
const appKeyRaw = hashParams.get("app_key");
const appKeyBase64 = appKeyRaw?.replace(/ /g, "+");
Then clear sensitive fragment from history.
window.history.replaceState({}, document.title, window.location.pathname + window.location.search);
Crypto recommendations
- Import app key with Web Crypto
- Use AES-GCM with random 96-bit IV per encryption
- Store
{iv + ciphertext} together
- Never reuse IV with same key
Failure modes to handle
- Missing key on first login for E2EE app (treat as setup failure)
- Identity switch returns different key context
- Key decode failures due to base64 normalization bug
- Fragment key left in browser history/logs
Last modified on April 13, 2026