Vencura
Architecture

Account linking

Change email vs link email, OAuth provider linking, provider trust, and guardrails.

Overview

Account linking lets users attach additional sign-in methods (email, OAuth providers, wallets) to an existing account. Two primary patterns exist: change email (replace primary email) and link email / OAuth (add methods without removing existing ones).

CapabilityChange emailLink email
EffectReplaces users.emailAdds a linked method; primary email unchanged
FlowRequest → verify code/link → updateRequest → verify link → link account
Use caseUser changes email addressUser adds email sign-in to OAuth-only account

Change email uses change_email verification type; link email uses link_email. Both use the same 6-digit + link UX and 15-minute TTL.

OAuth provider linking

Logged-in users can link additional OAuth providers from Profile (Settings). The backend:

  • Uses oauth_link_state (distinct from oauth_state for sign-in)
  • Binds the link to meta.userId so the exchange attaches to the correct account
  • Stores meta.redirectUri for Google (from redirect_uri query) when multiple callback URLs are configured (web + mobile)
  • Returns 409 PROVIDER_ALREADY_LINKED when the provider is linked to another user
  • Returns redirectTo so the client can return the user to the settings page after success

For Google, when using multiple callback URLs (e.g. web + mobile app), the client passes redirect_uri in the link-authorize-url request. It must be in the allowlist (OAUTH_GOOGLE_CALLBACK_URLS). See Authentication for full Google OAuth setup.

Provider trust

OAuth providers are trusted for identity on first link. Subsequent links require re-authorization; existing tokens are replaced on each successful link.

Guardrail: last sign-in method

Users must keep at least one sign-in method. Unlinking (wallet, OAuth, or other methods) fails with 400 LAST_SIGN_IN_METHOD if it would leave no way to sign in.

Verify modes (change email)

Verification accepts exactly one of:

  • { token, email } — code entry flow; email used as identifier
  • { token, verificationId } — link-click flow; verificationId from callback URL

See Authentication for full flow details.

On this page