Encryption scopes
Enable encryption by requesting ane2ee:* scope at sign-in. No developer-portal configuration is required.
Request exactly one E2EE mode scope per sign-in. Re-sign-in reuses existing per-app keys unless you also request
e2ee:reset:
mergeAppEncryptionFromUrl (PKCE) or completeOAuthCallback (session helper). Store the private key locally in your app; persist the public key on your user record.
On key rotation (e2ee:reset), the fragment also includes previous keys (#app_key_old, #app_public_key_old, #app_private_key_old) and #app_key_reset=true so your app can migrate ciphertext before discarding the old material.
Multi-user encryption (asymmetric)
Look up another user’s app public key, encrypt for them, and they decrypt with the private key you already stored locally.Lookup API
Public endpoint (no user token). Returns 404 if the handle is unknown, the user has never signed in to your app, or they have not provisioned an app encryption key — your app should show messaging like “this person hasn’t used your app yet” instead of generating keys server-side.GET /api/encryption/app-lookup?client_id=…&handle=…→ public key + user metadataGET /api/encryption/app-lookup?client_id=…&public_key=…→ user metadata for that key
Symmetric mode (legacy-compatible)
Older apps withsupportsE2ee still default to symmetric when no e2ee:* scope is requested. The flow is unchanged: #app_key= in the redirect fragment.
Removed: identity wrapped OAuth payloads
The oldwrapped_key / unwrapped_secret authorize flow is removed. It required per-identity encryption keys and sent users back through Ave for every invite. Use app keypairs and the lookup API instead.
Ave Signing (Ed25519) is unchanged and separate from app encryption.