VibeWeek
Home/Grow/Social Login & OAuth Implementation: Sign in with Google, GitHub, Apple, Microsoft Without Identity-Merging Disasters

Social Login & OAuth Implementation: Sign in with Google, GitHub, Apple, Microsoft Without Identity-Merging Disasters

⬅️ Day 6: Grow Overview

If you're running a SaaS in 2026, "Sign in with Google" is table stakes — most users expect it; signup conversion drops measurably without it. Most founders ship Google login on day one with whatever their auth library suggests, then six months later discover account-merging bugs (one user has two accounts: Google + email/password from the same email), provider-lockout (Google deprecates an API; users can't log in for a day), and the dreaded "Sign in with Apple" approval rejection because they didn't implement Apple''s privacy requirements correctly.

A working social-login implementation answers: which providers to support, how to handle account-linking across providers, how to handle provider failures, what happens when users change their email at the provider, and how to comply with provider-specific rules (Apple''s name/email handling). Done well, social login increases signup conversion by 10-30% and stays invisible. Done badly, you have weekly support tickets about lost accounts and bizarre identity-conflict bugs.

This guide is the implementation playbook for OAuth-based social login — provider selection, account-linking strategy, edge cases (Apple privacy mode, email changes, provider lockouts), security considerations, and the discipline that prevents identity-bug disasters. Distinct from SSO & Enterprise Auth (which covers SAML / OIDC for enterprise IT-managed access).

Pick Your Providers — Not All Are Equal

The first question: which "Sign in with X" buttons do you offer?

Help me pick social-login providers.

The candidates:

**Google (Sign in with Google)**

- Coverage: ~50-70% of users globally have Google accounts
- B2B: high (Google Workspace dominant)
- Free; mature OAuth implementation
- Conversion lift: 10-20% on signup

Should you support: YES (almost always)

**GitHub (Sign in with GitHub)**

- Coverage: developers / technical audiences
- Niche: dev tools, AI, open-source-adjacent
- Free; mature OAuth

Should you support: YES if your audience is developers; SKIP for general B2B

**Apple (Sign in with Apple)**

- Coverage: iOS / macOS users; mandatory for App Store apps with social login
- Privacy-strong: Apple offers email-relay (anonymized email)
- Free; complex implementation (privacy requirements)

Should you support: YES if you have iOS/macOS app or consumer-skewing audience; OPTIONAL otherwise

**Microsoft (Sign in with Microsoft)**

- Coverage: Microsoft 365 users (significant in B2B / enterprise)
- B2B: very high (Office 365 / Outlook users)
- Free; OIDC-based

Should you support: YES for B2B SaaS; OPTIONAL for consumer

**LinkedIn**

- Coverage: B2B professional audiences
- Less common as primary login
- API limits / rate-limits frustrating

Should you support: rarely; usually not worth the implementation overhead

**Facebook / Twitter (X)**

- Coverage: declining; users increasingly avoid
- Less common in SaaS
- Trust issues for some audiences

Should you support: rarely (consumer apps only)

**Slack / Discord / Notion / Linear**

- Niche: when integrating with these specific tools
- Use OAuth for "connect to" feature, not primary login

Should you support: only when product-specific

**Email / Password**

- Always support (fallback for users without preferred provider)
- Don''t make it second-class

**Magic Link (email-only auth)**

- No password; click email link to sign in
- Modern UX
- Increasingly common in 2026
- Per [Better Auth](https://www.vibereference.com/auth-and-payments/better-auth) and others support

Should you support: optional; consider as primary alternative to password

**The "default for B2B SaaS in 2026" recommendation**:

- Google (always)
- Microsoft (most B2B)
- Email / password OR magic link (fallback)
- GitHub (if developer audience)
- Apple (if iOS app or consumer)

Don''t support more than 4-5 providers. Each adds:
- Signup-flow UI complexity
- Maintenance burden
- Account-linking edge cases
- Support tickets

For my product:
- Audience characterization
- Provider selection
- The "must have" / "nice to have" / "skip" lists

Output:
1. The provider choice
2. The "we don''t support" list (and why)
3. The fallback mechanism

The biggest unforced error: supporting every provider. "Sign in with Google / GitHub / Apple / Microsoft / LinkedIn / Twitter / Facebook" — eight buttons; UI feels like 2014; conversion drops because users freeze. The fix: 3-4 providers max; pick by audience; one unmistakable default ("Sign in with Google" prominent; others smaller).

The Account-Linking Decision

The hardest part of social login isn''t the OAuth handshake. It''s identity merging.

Help me design account-linking.

The core problem:

- User signs up with email/password using `bob@acme.com`
- Later, user clicks "Sign in with Google" using same `bob@acme.com`
- Now: do they have two accounts? Or one?

This is the account-linking question. Get it wrong; users lose data.

**The three policies**:

**Policy A: Match by email; auto-link**

If a Google account''s email matches an existing user''s email: log them into that user.

Pros:
- Best UX; "it just works"
- One identity per email

Cons:
- Security risk: if attacker controls a Google account with target''s email, they can take over
- Email isn''t verified in OAuth from all providers (some return unverified)

Mitigation:
- Only auto-link if Google verified the email
- Send confirmation email when linking happens

**Policy B: Match by email; require confirmation**

Same as A, but explicit confirmation step:
- "We see you have an account with this email. Verify by clicking link in your email to link Google to it."

Pros:
- Safer (verified email at both ends)
- User aware of linking

Cons:
- Friction
- Some users abandon

**Policy C: Strict — never auto-link**

Each provider creates a separate account. User can manually link in settings.

Pros:
- No security risk
- Explicit user action

Cons:
- "I have two accounts now; my data is split"
- Bad UX

**The 90% answer**:

Policy A (auto-link on verified email) is right for most B2B SaaS.

- Use OAuth provider''s "email_verified" flag (Google: yes; GitHub: maybe; Apple: yes if shared)
- Only auto-link when verified == true
- Send notification when linking occurs

For consumer / sensitive contexts: Policy B.

**The "primary" account concept**:

Some teams pick a "primary" auth method per user:

- User signed up with Google; Google is primary
- Email is sourced from Google
- If they later change Google email: ?

This adds complexity. Most modern auth (Better Auth, Clerk, Supabase Auth) handle this with a "user has multiple accounts" model.

**The "email change" edge case**:

- User signs up with `bob@oldcompany.com` via Google
- User changes their Google email to `bob@newcompany.com`
- Next time they sign in: which user?

Options:
- Google email is now different; treat as different user (creates duplicate)
- Match by Google ID (subject claim) — this is what auth libraries do
- Update the email on the existing user

Best practice: match by **Google ID (the `sub` claim)**, not email. Email is mutable; ID isn''t.

**The schema implication**:

```sql
CREATE TABLE users (
  id UUID PRIMARY KEY,
  email TEXT UNIQUE,  -- can change
  primary_email_verified_at TIMESTAMPTZ,
  ...
);

CREATE TABLE user_oauth_accounts (
  user_id UUID REFERENCES users(id),
  provider TEXT NOT NULL,  -- 'google', 'github', 'apple'
  provider_account_id TEXT NOT NULL,  -- the immutable provider ID
  email TEXT,  -- email at time of link
  email_verified BOOLEAN,
  linked_at TIMESTAMPTZ DEFAULT now(),
  PRIMARY KEY (provider, provider_account_id)
);

User has many OAuth accounts; each linked separately.

For my system:

  • Linking policy
  • Schema design
  • Edge cases handled

Output:

  1. The linking policy
  2. The schema
  3. The verification rules

The biggest account-linking mistake: **matching only by email.** User changes Google email → creates duplicate user account → data scattered. Or: user has Google + email/password without verification → attacker creates Google account with target email → takes over. The fix: match by provider-side immutable ID (`sub`); only auto-link when email-verified at both ends.

## The OAuth Flow — Get the Mechanics Right

OAuth has subtle pitfalls. Use the right pattern.

Help me implement OAuth correctly.

The standard OAuth 2.0 / OIDC flow:

Step 1: Redirect to provider

// User clicks "Sign in with Google"
const state = randomString(32);
const codeVerifier = randomString(64);
const codeChallenge = sha256(codeVerifier);

// Save state + verifier in session
session.set('oauth_state', state);
session.set('oauth_code_verifier', codeVerifier);

const url = new URL('https://accounts.google.com/o/oauth2/v2/auth');
url.searchParams.set('client_id', GOOGLE_CLIENT_ID);
url.searchParams.set('redirect_uri', '/auth/google/callback');
url.searchParams.set('response_type', 'code');
url.searchParams.set('scope', 'openid email profile');
url.searchParams.set('state', state);
url.searchParams.set('code_challenge', codeChallenge);
url.searchParams.set('code_challenge_method', 'S256');

redirect(url.toString());

Step 2: Provider redirects back to /auth/google/callback

// User has signed in to Google; provider redirects with `code` and `state`
const { code, state } = getQueryParams();

// Verify state matches (CSRF protection)
if (state !== session.get('oauth_state')) {
  throw new Error('OAuth state mismatch');
}

// Exchange code for tokens
const tokenResponse = await fetch('https://oauth2.googleapis.com/token', {
  method: 'POST',
  body: new URLSearchParams({
    grant_type: 'authorization_code',
    code,
    client_id: GOOGLE_CLIENT_ID,
    client_secret: GOOGLE_CLIENT_SECRET,  // SERVER-SIDE ONLY
    redirect_uri: '/auth/google/callback',
    code_verifier: session.get('oauth_code_verifier'),
  }),
});
const { id_token, access_token } = await tokenResponse.json();

// Verify and decode id_token (JWT)
const claims = await verifyJWT(id_token, googlePublicKeys);

// claims.sub = unique Google user ID
// claims.email, claims.email_verified, claims.name, claims.picture

Step 3: Find or create user

// Look up by provider + provider_account_id
let oauthAccount = await db.userOauthAccounts.findUnique({
  where: { provider: 'google', provider_account_id: claims.sub },
});

if (oauthAccount) {
  // Existing user; sign them in
  const user = await db.users.findById(oauthAccount.user_id);
  await createSession(user);
  return redirect('/dashboard');
}

// Try to link by email (if verified)
if (claims.email_verified) {
  const existingUser = await db.users.findByEmail(claims.email);
  if (existingUser) {
    // Link Google account to existing user
    await db.userOauthAccounts.create({
      user_id: existingUser.id,
      provider: 'google',
      provider_account_id: claims.sub,
      email: claims.email,
      email_verified: true,
    });
    await createSession(existingUser);
    return redirect('/dashboard');
  }
}

// New user
const user = await db.users.create({
  email: claims.email,
  name: claims.name,
  primary_email_verified_at: claims.email_verified ? new Date() : null,
});
await db.userOauthAccounts.create({
  user_id: user.id,
  provider: 'google',
  provider_account_id: claims.sub,
  email: claims.email,
  email_verified: claims.email_verified,
});
await createSession(user);
redirect('/onboarding');

Critical security rules:

  1. Use PKCE (code_verifier / code_challenge) — protects against authorization-code interception
  2. Verify state parameter — CSRF protection
  3. Verify ID token signature — don''t trust unverified JWTs
  4. Server-side client_secret — never expose to browser
  5. HTTPS-only — OAuth must use HTTPS
  6. Validate audience claim — id_token''s aud must match your client_id

What auth libraries handle:

Modern auth libraries (Better Auth, NextAuth.js / Auth.js, Clerk, Supabase Auth) handle most of this. But you should understand what they''re doing.

Per auth-providers: pick a provider that handles OAuth well; trust the abstraction.

For my system:

  • Auth library choice
  • Custom needs (if any)
  • Security verification

Output:

  1. The OAuth flow implementation
  2. The library choice
  3. The custom-handling needs

The biggest OAuth-implementation mistake: **rolling your own OAuth.** "I''ll just write a small OAuth client myself" — six months in, you have CSRF / PKCE / token-validation bugs. Use a library (Better Auth / NextAuth / Clerk / etc.); customize only what''s necessary.

## Apple Sign-In Specifics

Apple has unique requirements. Get them right or App Store rejects you.

Help me implement Apple Sign-In correctly.

Apple-specific rules:

1. App Store mandate

If your iOS / macOS app supports any third-party login (Google / Facebook / etc.), you MUST also support Sign in with Apple.

Web-only apps don''t need it; iOS app does.

2. Email Relay

Apple offers users a privacy option: hide my real email; provide a relay address.

  • User signs up with xyzabc123@privaterelay.appleid.com
  • Apple forwards emails to user''s real email
  • You never see the real email

Implications:

  • Don''t treat this email as the user''s "real" email
  • User-facing references should use name or "you" not the email
  • If user revokes Apple access: relay stops working

3. Name only available on first sign-in

Apple shares the user''s name in the FIRST OAuth response only. After that, you don''t get it.

const { user } = await fetch('https://appleid.apple.com/auth/token');

// First sign-in: includes user.name
// Subsequent: only user.sub

if (firstSignIn && claims.name) {
  await db.users.create({ name: claims.name, ... });
}

If you miss the name on first sign-in: the user has no name in your system unless they fill it later.

4. Token verification

Apple''s ID tokens follow OIDC but with quirks:

  • Uses Apple-specific public keys (rotate frequently)
  • Audience claim: your client_id
  • Issuer: https://appleid.apple.com

Use a library (jose or similar) to verify.

5. Refresh-token rotation

Apple refresh tokens have specific rotation requirements. If you persist refresh tokens to keep users signed in:

  • Refresh < every 24 hours
  • Apple revokes if too long

Most flows: just use ID token; don''t persist refresh.

6. App-bound vs web-bound flow

Different setups for iOS app vs web:

  • iOS: native Apple Sign-In SDK
  • Web: redirect-based OAuth flow

You may need both if you have both clients.

7. Account-deletion implications

Apple requires you to support account deletion (App Store Guideline 5.1.1(v)).

If user signs up via Apple: provide in-app "delete my account" flow.

Per account-deletion-data-export-chat.

For my Apple implementation:

  • Web vs iOS context
  • Email-relay handling
  • First-sign-in name capture
  • Account-deletion compliance

Output:

  1. The Apple-specific handling
  2. The first-sign-in special case
  3. The compliance checklist

The biggest Apple-Sign-In mistake: **missing the name on first sign-in.** First OAuth response includes name; subsequent doesn''t; user is "Anonymous User" forever in your DB. The fix: on first sign-in, capture name from token response; persist it; never expect to receive it again.

## Account-Recovery Edge Cases

What happens when users lose access to their OAuth provider? Plan for it.

Help me handle account recovery.

The scenarios:

Scenario 1: User loses Google access

User signed up with Google; their Google account is suspended / they lost access.

Options:

  • Allow signing in via email/password (they need to set one)
  • Send "magic link" to their email
  • Manual support recovery (verify identity)

Pre-emptively prevent:

  • Encourage users to set a password OR add email/magic-link as backup
  • Require multiple auth methods for paid users

Scenario 2: User changes Google email

User signed up with bob@oldcompany.com Google; changes to bob@newcompany.com.

If you matched on Google ID (sub claim): user finds their account; just email is updated. If you matched on email only: duplicate account created.

This is why we match on sub.

Scenario 3: User has multiple Google accounts

User signed up with personal Google; tries signing in with work Google.

These are separate Google accounts (different sub). They''ll create two accounts in your system unless you let them link manually.

Solution: allow account-merging in settings (see below).

Scenario 4: User wants to remove Google linkage

User added Google in addition to email/password; now wants to remove Google.

Settings UI:

  • "Remove Google" button
  • Confirm
  • Delete the user_oauth_accounts row
  • User can still sign in via email/password

Scenario 5: User wants to merge accounts

User has account A (Google) and account B (email). They want one account.

Manual support process:

  • Verify they own both
  • Pick which to keep (data/billing implications)
  • Move data from one to the other
  • Delete the other

This is operationally heavy. Document the playbook.

Scenario 6: Provider OAuth service goes down

Google''s OAuth API is down for an hour. Users can''t sign in.

Mitigations:

  • Always offer email/password fallback
  • Existing sessions still work (don''t require re-auth on every page)
  • Status-page communication

The "always have a fallback" rule:

Every user MUST have a way to recover access without their primary provider:

  • Backup email
  • Password
  • Magic link to email
  • Recovery code

If a user signed up purely with Google and never set anything else: they''re vulnerable.

For my system:

  • Recovery options offered
  • Edge-case playbooks
  • The "set a backup" prompt

Output:

  1. The recovery flow
  2. The edge-case playbooks
  3. The backup-method enforcement

The biggest account-recovery mistake: **only OAuth, no fallback.** User loses Google access; their account in your product is locked forever. The fix: every user has at least one backup method (email + magic link, or password). Encourage on signup; require for paid users.

## Security Considerations

OAuth is a common attack vector. Harden against the obvious.

Help me secure OAuth implementation.

The threats:

1. CSRF on OAuth callback

Attacker tricks user into clicking attacker-prepared OAuth callback URL → user signs in to attacker''s session.

Prevention: state parameter (random string; verified server-side).

2. Authorization code interception

In some setups, code exposed to attacker via redirect-bouncing or referrer.

Prevention: PKCE (code_verifier / code_challenge) — code can''t be exchanged without verifier.

3. Token replay

Attacker reuses an old ID token.

Prevention: verify iat (issued-at) is recent; verify exp (expiration); verify nonce (if used).

4. Audience confusion

Attacker presents an ID token from a different app to your callback.

Prevention: verify aud (audience) matches your client_id.

5. Open redirect

OAuth flow can include a redirect_to parameter; attacker uses to phish.

Prevention: whitelist allowed redirect destinations; don''t trust user-supplied URLs.

6. Session fixation

Attacker creates a session, tricks user into authenticating into it.

Prevention: regenerate session ID after OAuth login.

7. Account takeover via email control

Attacker controls an email; signs up via OAuth provider with that email; takes over an existing user with that email.

Prevention:

  • Don''t auto-link unverified emails
  • Confirm linking out-of-band when possible

8. OAuth provider compromise

Provider''s OAuth keys leak; attacker forges tokens.

Prevention:

  • Verify token signature against provider''s current public keys (rotated)
  • Use library that handles this

9. Logout endpoints

User logs out of your app but stays logged into Google.

Most apps: that''s fine (don''t force Google logout). For shared-computer scenarios: allow Google logout via OIDC logout endpoint.

10. Refresh token theft

Long-lived refresh tokens stolen → persistent access.

Mitigations:

  • Rotate on each refresh
  • Bind to user agent / IP fingerprint
  • Revoke on suspicious activity

The library does most of this:

A reputable auth library (Better Auth, Clerk, etc.) handles 1-7 properly. You handle 8 (don''t paranoid-rebuild) and 9 (UX choice).

Audit your auth setup quarterly; check known CVEs.

For my security:

  • Audit current OAuth flow
  • Mitigations in place
  • Library checks

Output:

  1. The threat model
  2. The mitigation audit
  3. The library trust verification

The biggest security mistake: **building OAuth from scratch.** Every team that does this hits one of the 10 issues above eventually. The fix: use a tested library; understand what it does; trust the abstraction; audit quarterly.

## The Signup-Form UX

The login/signup page UX directly affects conversion. Get it right.

Help me design the social-login UI.

The proven layout:

Top: primary social-login

[ Sign in with Google ]   <- big button; brand colors
[ Sign in with Microsoft ]
[ Sign in with Apple ]

Middle: divider

─── or ───

Bottom: email

Email: [...]
Password: [...]
[ Sign in ]
[ Forgot password? ] [ Use magic link ]

Conversion principles:

  • Big, branded social-login buttons (use provider''s brand assets)
  • Clearly labeled (don''t use ambiguous icons-only)
  • Order matters: Google usually first (highest coverage); audience-specific next
  • Email/password / magic link as fallback (smaller; lower)

The "remember last method" pattern:

After first sign-in, remember which method the user used:

  • Next time, highlight that option
  • "You signed in with Google last time" badge

This reduces decision-paralysis on return visits.

The first-time-vs-returning distinction:

  • Signup page: "Sign up with Google / etc." (suggesting creation)
  • Login page: "Sign in with Google / etc." (suggesting return)

Same providers; different copy.

Mobile considerations:

  • Native iOS app: must use native Apple Sign-In (not web redirect)
  • Tap targets: 44px+ minimum
  • Mobile flow: provider redirects can be jarring; consider in-app browser

Provider brand assets:

Each provider has brand-asset guidelines:

  • Google: specific button design / colors
  • Apple: specific button (multiple styles allowed)
  • GitHub: octocat icon usage
  • Microsoft: specific brand

Follow them. Otherwise: rejected app store submissions; provider revoking your client.

Anti-patterns:

  • 8 social buttons (decision paralysis)
  • Tiny icon-only buttons (unclear)
  • Custom-styled buttons that violate brand guidelines (rejection risk)
  • Hidden "or sign in with email" (frustrating for non-OAuth users)
  • Email signup form by default; social hidden behind "Other ways to sign in" (conversion crusher)

For my UI:

  • Primary providers
  • Order
  • Mobile vs web
  • Brand-asset compliance

Output:

  1. The signup-form design
  2. The mobile flow
  3. The brand-asset checklist

The biggest UX mistake: **email-first signup with social-login hidden behind "Other ways."** Conversion drops 15-30% vs social-prominent. The fix: social-login is the primary path for most B2C / B2B SaaS; email is the fallback. Order: most-common provider first; fallback last.

## Test the Edge Cases

OAuth bugs are subtle. Test them.

Help me test OAuth flows.

The test cases:

1. Happy paths

  • New user via Google → account created; signed in
  • Returning user via Google → signed in
  • New user via email/password → account created; signed in

2. Account-linking

  • User signs up email/password; later signs in with Google (same email): linked
  • User signs up Google; later signs in with email/password: ?
  • User signs up Google personal; later Google work: separate accounts

3. Verified vs unverified

  • Google verified email: auto-linked
  • Provider with unverified email: requires manual confirmation

4. Apple-specific

  • First sign-in captures name
  • Email-relay address handled
  • Subsequent sign-in works without name

5. Edge cases

  • OAuth error (user cancels; provider down): graceful UI
  • Mismatched state (CSRF attempt): rejected
  • Replayed code: rejected
  • Expired session during OAuth: handled

6. Account merging

  • User has two accounts; merge flow
  • Data preservation after merge

7. Logout / session

  • Logout cleans session
  • Multiple sessions per user (work + personal devices)

8. Provider outages

  • Google OAuth fails: fallback to email
  • Apple keys rotate: handled

9. Email change at provider

  • User changes Google email: their account in your DB updated (matched by sub)

10. Account deletion

  • User deletes account: OAuth links removed
  • User signs in again with same provider: new account created (or refused)

Integration testing:

  • Mock OAuth provider in tests (don''t hit real Google in CI)
  • Tools: ngrok for local OAuth callbacks
  • Staging environment with real provider sandboxes

For my testing:

  • Test coverage gaps
  • CI integration
  • Manual-test playbook

Output:

  1. The test plan
  2. The CI integration
  3. The manual-test playbook

The biggest testing mistake: **only testing happy paths.** Production breaks on the edge cases — name missing for Apple; email change at Google; account-linking conflicts. The fix: explicit test for each edge case; integration tests with mocked providers; periodic real-provider manual testing.

## Avoid Common Pitfalls

Recognizable failure patterns.

The social-login mistake checklist.

Mistake 1: Roll-your-own OAuth

  • Subtle security bugs
  • Fix: use a library

Mistake 2: Match by email only

  • Email changes break; security risk
  • Fix: match by provider sub

Mistake 3: No fallback method

  • User loses provider access; locked out
  • Fix: always offer email/password or magic link

Mistake 4: Auto-link unverified emails

  • Account-takeover risk
  • Fix: only auto-link verified

Mistake 5: Apple name only on first sign-in missed

  • Users have no name forever
  • Fix: capture on first sign-in; persist

Mistake 6: Too many providers

  • 8 buttons; UI cluttered
  • Fix: 3-4 max

Mistake 7: No PKCE

  • Code-interception vulnerability
  • Fix: PKCE on all OAuth flows

Mistake 8: No state verification

  • CSRF vulnerability
  • Fix: state param required

Mistake 9: Missing logout endpoint

  • Users can''t fully log out
  • Fix: revoke session + tokens

Mistake 10: No account-merge flow

  • Users with split accounts; support nightmare
  • Fix: support-team playbook OR self-serve merge

The quality checklist:

  • Provider list (3-4 max; Google + appropriate)
  • Auth library used (not rolled own)
  • PKCE on OAuth flow
  • State verification
  • Match by provider sub (not email)
  • Verified-email auto-link only
  • Apple specifics handled (name capture; email-relay)
  • Account-deletion flow
  • Backup auth method enforced
  • Edge-case test coverage

For my implementation:

  • Audit
  • Top 3 fixes

Output:

  1. Audit results
  2. Top 3 fixes
  3. The "v2 social-login" plan

The single most-common mistake: **shipping social login at MVP without security or edge-case discipline.** "It works on the happy path"; production hits an edge case; account-takeover bug; fire-fight. The fix: pick a battle-tested auth library; understand what it handles vs you; audit before launch; keep an edge-case test suite.

---

## What "Done" Looks Like

A working social-login system in 2026 has:

- 3-4 providers (Google + Microsoft + Apple/GitHub + email fallback)
- Auth library handling OAuth mechanics (not rolled-your-own)
- Match by provider sub; auto-link verified emails only
- Apple-specific handling (name on first sign-in, email-relay)
- Backup auth method enforced for paid users
- Account-merge / linking flows
- Edge-case test coverage
- Branded buttons matching provider guidelines
- Logout + session management correct
- Quarterly security audit

The hidden cost of weak social-login: **account-conflict support tickets that scale.** Every week, a user with split accounts; an Apple user with no name; a "Google said I logged in but your app says no" ticket. These compound. A robust implementation prevents the support hell. Pick a library; implement carefully; test edge cases. Pays back constantly.

## See Also

- [SSO & Enterprise Auth](sso-enterprise-auth-chat.md) — enterprise SAML/OIDC (different audience)
- [Two-Factor Auth](two-factor-auth-chat.md) — adjacent security
- [Roles & Permissions](roles-permissions-chat.md) — auth + authz
- [Multi-Tenancy](multi-tenancy-chat.md) — tenant-aware auth
- [Account Deletion & Data Export](account-deletion-data-export-chat.md) — Apple compliance
- [Audit Logs](audit-logs-chat.md) — auth events
- [API Keys](api-keys-chat.md) — programmatic access
- [Email Deliverability](email-deliverability-chat.md) — magic-link emails
- [VibeReference: Auth Providers](https://www.vibereference.com/auth-and-payments/auth-providers) — Clerk / Better Auth / Supabase Auth
- [VibeReference: Better Auth](https://www.vibereference.com/auth-and-payments/better-auth) — modern OSS
- [VibeReference: Authentication](https://www.vibereference.com/auth-and-payments/authentication) — fundamentals
- [VibeReference: Login with Google](https://www.vibereference.com/auth-and-payments/login-with-google) — Google deep-dive
- [VibeReference: Passkeys](https://www.vibereference.com/auth-and-payments/passkeys) — passwordless future
- [VibeReference: Identity Verification & KYC Tools](https://www.vibereference.com/auth-and-payments/identity-verification-kyc-tools) — different problem
- [LaunchWeek: Trust Center & Security Page](https://www.launchweek.com/4-convert/trust-center-security-page) — security messaging

[⬅️ Day 6: Grow Overview](README.md)