# Familiar accounts, one sign-in integration

Google and GitHub can share your application’s callback and profile contract without becoming interchangeable identities. This note separates the provider choice users see from the integration and account decisions your backend owns.

By Gabe. Published 2026-10-06.
Author: https://anyoauth.com/blog/authors/gabe/
Source: https://anyoauth.com/blog/familiar-accounts-one-sign-in-integration/

1. Browser: selects configured Google or GitHub sign-in
2. AnyOAuth: handles the provider-specific identity check
3. Your backend: uses the same exchange and profile contract

The application contract stays consistent while the upstream identity mechanisms remain provider-specific.

Put two buttons beside the same callback route: “Continue with Google” and “Continue with GitHub.” Both can lead to the same backend exchange and user lookup. The database decision after that lookup is where the buttons stop being merely presentation. A Google account and a GitHub account are separate identities, even when a person uses both.

Before writing those buttons, check which providers are enabled. Current AnyOAuth support is Google and GitHub, and availability depends on configured service applications. A provider logo on a page is not an availability guarantee. Build the sign-in choices around the actual service configuration, not an assumed catalogue of every OAuth provider.

## Standardize the application boundary, not the upstream protocol

One integration means one customer-facing contract, not identical provider responses. Google supplies OIDC identity evidence. AnyOAuth validates its signature, issuer, audience, lifetime, and transaction nonce. GitHub uses OAuth followed by fresh server-side profile and email lookup. GitHub's own documentation recommends revalidating identity every time an access token is received.

Your backend doesn't need to turn those two paths into two session implementations. It redirects through `/authorize`, redeems the returned AnyOAuth handoff code at `/v1/token`, and retrieves the normalized identity at `/v1/profile`. The [OAuth versus OIDC reference](/blog/oauth-vs-oidc/) explains the upstream distinction without suggesting that AnyOAuth itself is a general OIDC provider.

| Integration concern | Shared by your app | Still varies or stays separate |
| --- | --- | --- |
| Customer credentials | Project client ID and backend secret | Independent apps can have separate projects |
| Callback protection | Registered exact callback, state, S256 PKCE | Each login has its own transaction |
| User lookup | Stable normalized `subject` | Project, provider, and provider subject define the identity |
| Display fields | Consistent profile field names | Names, usernames, emails, and avatars may be null |
| Provider access | No provider token handling in your app | Provider-specific evidence stays inside the service |

For a coding assistant, that table is a better constraint than “add social login.” It says which code should be shared and which facts must remain distinguishable. You can inspect a single callback handler while still preserving the provider field in your user-facing account information.

## Equal email addresses must not collapse two users

Account matching belongs to the stable identity, not to an attractive-looking profile field. Google's documentation explicitly warns against using email as the unique identifier. AnyOAuth extends the application's boundary with project-scoped subjects, and it doesn't automatically merge accounts by email.

<figure class="article-diagram"><ol><li><strong>Google path:</strong> project A plus Google plus its provider subject resolves to one AnyOAuth subject. Its email is profile data.</li><li><strong>GitHub path:</strong> project A plus GitHub plus its provider subject resolves to another subject, even if the returned email matches.</li><li><strong>Application lookup:</strong> your backend finds users by stable subject. It must not silently attach the second identity to the first user through an email lookup.</li></ol><figcaption>Normalization changes the response shape, not account ownership. Matching email values do not establish a link between provider identities.</figcaption></figure>

This means a person choosing a different provider can arrive as a different app user. Explain that consequence in account and recovery UI. AnyOAuth currently has no account-linking feature. If your product needs linking, specify proof of control and recovery behavior before adding an email-based shortcut; don't let a generated database upsert invent that policy.

The [one-profile note](/blog/one-profile-every-provider/) covers nullable fields, while [project credentials](/blog/stop-juggling-oauth-client-ids-and-secrets/) explains why sharing an integration pattern doesn't require sharing every app's secret.

## Familiar buttons still lead to the service’s consent identity

Provider consent branding is part of the login experience. Users see AnyOAuth's provider application identity, not a separate provider registration created under your app's name. Tell users what the service does where that explanation is useful. If your requirement is your own upstream consent identity, evaluate direct provider integration rather than assuming callback configuration changes branding.

Keep access requests equally clear. This is identity-only sign-in, not a request to import repositories or calendars. The opaque profile token lasts 15 minutes, has no refresh flow, and cannot call provider APIs. Your app creates and manages its own session after retrieving the profile.

## AnyOAuth implementation choice

AnyOAuth, which we build, fits apps that want those two configured providers behind one profile handoff. Create a project, retain its client ID and backend secret, and register an exact callback. Redemption still requires the original verifier and client authentication; the two-minute handoff code is single-use.

The DIY alternative is separate Google and GitHub registrations with a maintained library handling their different validation paths. Choose that when provider-specific scopes or branding are part of the product. For a full session and account-management platform, evaluate a broader auth system such as Auth0 or Clerk against your requirements. AnyOAuth's narrower contract doesn't supply those features, OIDC discovery, or SAML federation.

## Check both paths, including missing fields

Review Google and GitHub independently: an enabled button, a completed callback, a stable subject, and a usable screen when display fields are absent. Also review a denial and a second provider with the same email. Neither should bypass transaction checks or your account policy.

Then follow the [redirect, exchange, profile trace](/blog/redirect-exchange-profile/) to connect the shared integration to the app session. Privacy duties remain yours; a uniform profile format doesn't establish automatic compliance.

## Sources

Read or retrieved 2026-10-06:

- AnyOAuth, [Quickstart and provider availability](/docs/), [Security model](/security/), and [Privacy responsibilities](/compliance/).
- Google, [OpenID Connect](https://developers.google.com/identity/protocols/oauth2/openid-connect), including ID-token validation and stable subject guidance.
- GitHub, [Authorizing OAuth apps](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/authorizing-oauth-apps), including fresh identity lookup after exchange.