The pieces
Passkey accounts
Users authenticate with a passkey. Each account can hold several identities, and each identity is a separate principal to your app.
OAuth 2.0 and OIDC
Authorization code flow with PKCE, ID tokens, access tokens, and rotating refresh tokens.
App encryption keys
Per-app, per-identity keys, wrapped by the user’s master key on Ave and unwrapped only on the user’s device.
Sign-in
1
Your app sends the user to Ave
Your app opens
https://aveid.net/signin with its client_id, redirect_uri, scopes, PKCE challenge, state, and nonce, either by redirecting or through the embed.2
The user authenticates and consents
The user signs in with a passkey, picks an identity, and approves the scopes your app asked for.
3
Ave redirects back
Ave returns to your
redirect_uri with ?code=...&state=.... If your app asked for an encryption scope, the keys follow in the fragment: #app_key=....4
Your app exchanges the code
Your app sends the code and PKCE verifier to
POST https://api.aveid.net/api/oauth/token and receives an id_token, access tokens, and, with offline_access, a refresh token.5
Your app creates its session
Verify the
id_token, key your records by its sub, and keep the encryption key on the client.Encryption keys
Every Ave account has a master key. It is generated on the user’s device and stored on Ave only in encrypted form, unlocked with passkey PRF output, a recovery code, or a transfer from another signed-in device. The master key never leaves the device in plaintext. When an app first asks fore2ee:symmetric or e2ee:asymmetric, the Ave sign-in page generates the app’s key material in the browser, encrypts it with the master key, and stores only that ciphertext on the authorization. On every later sign-in, the page decrypts the stored ciphertext locally and places the plaintext in the callback fragment. Fragments are not sent in HTTP requests, so the plaintext reaches your client code without passing through Ave’s API or your server.
Keys are stable per app and identity. A user who signs in again, or on another device, gets the same key. A different identity gets different keys. Rotation only happens when your app asks for it with e2ee:reset.
See Encryption model and key lifecycle for details.
Responsibilities
Ave tells you who the user is and delivers their keys. What that identity is allowed to do in your app is decided by your app. See App workspaces and permissions.
