Choose a mode
Request one encryption scope per sign-in. Nothing needs to be enabled in the developer portal.e2ee:pqc:kyber and e2ee:pqc:dilithium are reserved names and return unsupported_encryption_mode.
Asking for both modes in one request returns invalid_scope. Signing in again reuses the existing keys, so request the same mode every time.
Request the scope
Receive the keys
After consent, Ave redirects with the code in the query string and the keys in the fragment:
The keys are never included in the token endpoint response. The SDK reads them from the fragment and merges them into the token response for you:
completeOAuthCallback(session, options)from@ave-id/sdk/clientexchanges the code, merges the keys, removes them from the address bar, and saves them in the session.onTokensin@ave-id/embedreceives the merged token response directly.mergeAppEncryptionFromUrl(url, tokens)from@ave-id/sdkmerges them into a token response you exchanged yourself. CallstripSensitiveFragmentParams()afterwards.
AveSession:
AveSession keeps the keys in the storage adapter you give it, next to the tokens. createLocalStorageAdapter() persists them across reloads. Because Ave delivers the same key on every sign-in, createMemoryStorage() or your own AveSessionStorage implementation work too if you would rather not keep keys at rest in the browser.
Symmetric mode
Import the key as an AES-GCM key and use a fresh 12-byte IV for every encryption.Asymmetric mode
Each user gets a P-256 keypair for your app. Ave stores the public key in plaintext so other users of your app can look it up, and stores the private key wrapped by the user’s master key.Encrypt for another user
encryptForAppHandle looks up the recipient’s public key for your app and encrypts with an ephemeral ECDH key and AES-GCM. No round trip through the recipient is needed.
encryptForAppUser(payload, publicKey) instead.
Decrypt
The recipient decrypts with the private key from their session:Look up users
404 when the handle does not exist, the identity has never authorized your app, or it has no asymmetric key yet. Show an invitation instead of generating keys on the user’s behalf. Lookups are scoped to a client ID, so a user’s public key for your app is unrelated to their keys for any other app.
Store each user’s public key on your own user record as well. Lookups by handle follow handle changes, but your records should point at the identityId.
Rotate keys
Adde2ee:reset to a sign-in to replace the user’s keys for your app. The consent screen warns the user that their previous keys will be replaced.
*_old parameters, and app_key_reset=true. Decrypt existing data with the old key, re-encrypt it with the new key, then discard the old key. Only request e2ee:reset from an explicit user action; a normal sign-in never rotates keys.
Identities and devices
- Keys belong to one app and one identity. Switching identity means switching key context; keep each identity’s ciphertext separate.
- The same identity gets the same keys on every device where its Ave account is unlocked.
- Different apps get different keys. Another app cannot request yours.
- When a user disconnects your app in Ave, its wrapped keys for that identity are deleted and the next sign-in provisions new ones. If your data must survive that, keep an encrypted backup of the key under your own recovery scheme.
Failure modes
See the integration checklist, the encryption model, and the SDK reference.
