> ## Documentation Index
> Fetch the complete documentation index at: https://docs.praxis-ai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Social Login (Google, GitHub, Facebook)

> Let users sign in with their existing Google, GitHub, or Facebook account.

Social login lets users sign in to Pria with an account they already have. Pria runs the OAuth 2.0 Authorization Code flow on the server: the user is redirected to the provider, signs in there, and comes back with a one-time code that Pria exchanges for an access token server-to-server. The provider's client secret never reaches the browser.

On first sign-in, Pria provisions a new user account from the provider's profile (email, first name, last name, profile picture). On subsequent sign-ins, the existing account is reused.

***

## Providers

<Tabs>
  <Tab title="Google">
    Google is the most-used social login on Pria. In addition to the **Sign in with Google** button, the login page supports Google **One Tap** — users already signed in to Google in their browser can sign in to Pria with a single click on the One Tap prompt.

    Two configuration levels exist:

    * **Platform-level (default)** — A single Google OAuth client configured at the platform level handles all `Sign in with Google` buttons. This is the out-of-the-box behaviour.
    * **Institution-level (optional)** — An institution admin can register their own Google OAuth client (under their Google Cloud project) and connect it to the institution. Members of that institution then authenticate against the institution's Google app, with the institution's branding on the consent screen. See [Google Workspace integration](/mdx/integrations/google-workspace/overview).

    <Info>When both levels are configured, the institution-level client takes priority for users associated with that institution.</Info>

    **Scopes requested at sign-in:** `openid profile email`. Pria stores `access_type=offline` so a refresh token is returned, enabling later access to optional Google services (Gmail, Drive, Calendar, Sheets, Docs) that the user can grant from their [profile page](/mdx/user-guide/profile-settings/google-services).

    **Redirect URL to register in Google Cloud:**

    ```
    https://your-domain.com/api/auth/google/callback
    ```

    For production: `https://pria.praxislxp.com/api/auth/google/callback`.
  </Tab>

  <Tab title="GitHub">
    GitHub social login is most useful for developer-leaning audiences — early adopters, technical evaluators, and customers who already have a GitHub account they trust.

    **Scopes requested at sign-in:** `read:user user:email`.

    Pria first reads the `email` claim from the GitHub profile. If the user has marked their email private on GitHub, Pria falls back to `GET /user/emails` to pick the primary verified address. If none is exposed, Pria uses the GitHub `noreply` form `<id>+<login>@users.noreply.github.com` so the account can still be created.

    **Redirect URL:**

    ```
    https://your-domain.com/api/auth/github/callback
    ```

    <Note>The same GitHub OAuth app can also act as a **GitHub Marketplace listing** endpoint. Pria's GitHub callback handles marketplace `purchased`, `changed`, `cancelled`, and pending-change webhooks for billing automation — but that's an optional feature that doesn't affect the sign-in flow.</Note>
  </Tab>

  <Tab title="Facebook">
    Facebook sign-in uses **Graph API v19.0**.

    **Scopes requested at sign-in:** `email,public_profile`. Pria pulls only the minimum profile fields needed to provision an account (`id,name,email,picture`).

    **Email fallback:** Facebook does not always return an email — users can sign up with a phone number, or mark their email hidden. When `email` is missing or `null`, Pria synthesises an internal identifier of the form `<facebookId>@facebook.com` so the account can be created. The user can update their email later from their profile.

    **Name parsing:** Facebook returns a single `name` string. Pria splits on whitespace: first token → first name, remainder → last name. Single-word names default to `User Facebook`.

    **Redirect URL:**

    ```
    https://your-domain.com/api/auth/facebook/callback
    ```
  </Tab>
</Tabs>

***

## Setup steps (any provider)

<Steps>
  <Step title="Register an OAuth app with the provider">
    Create an OAuth 2.0 application in your provider's developer console:

    * **Google:** [Google Cloud Console → APIs & Services → Credentials](https://console.cloud.google.com/apis/credentials), create an **OAuth 2.0 Client ID** of type *Web application*.
    * **GitHub:** [GitHub Settings → Developer settings → OAuth Apps → New OAuth App](https://github.com/settings/developers).
    * **Facebook:** [Meta for Developers → My Apps → Create App](https://developers.facebook.com/apps/), add the *Facebook Login* product.

    Note the **Client ID** and **Client Secret** — you'll need both.
  </Step>

  <Step title="Add the redirect URL">
    Register Pria's callback URL with the provider. Use the production callback for the production instance, and add a separate dev callback if you're testing locally:

    ```
    https://pria.praxislxp.com/api/auth/google/callback
    https://pria.praxislxp.com/api/auth/github/callback
    https://pria.praxislxp.com/api/auth/facebook/callback
    ```

    <Warning>The redirect URL must match **exactly** what's registered with the provider. A trailing slash, `http` vs `https`, or a port mismatch will cause an `invalid_redirect_uri` error.</Warning>
  </Step>

  <Step title="Configure Pria with the client ID + secret">
    For the **platform-level** Google / GitHub / Facebook clients, the Praxis AI team configures these environment values for you. Contact [humans@praxis-ai.com](mailto:humans@praxis-ai.com) to request platform-level provider configuration.

    For the **institution-level Google client**, an institution admin can self-configure it from the institution settings page — see [Google Workspace integration](/mdx/integrations/google-workspace/overview).
  </Step>

  <Step title="Test sign-in">
    From the Pria login page, click **Sign in with Google / GitHub / Facebook**. You'll be redirected to the provider, then back to Pria's `/oauth/success` page, then into the app.

    If anything goes wrong, the `/oauth/success` page surfaces a query-string error code — `oauth_failure`, `no_code`, `invalid_state`, `state_mismatch`, `state_expired`, `no_token`, `invalid_account`, or `registration_failed` — to help diagnose the failure.
  </Step>
</Steps>

***

## Account merging

Pria identifies users by **email address**. If a user signs in with Google using `alice@example.com` and an account with that email already exists (whether it was created by email + password, by GitHub, by Facebook, or by SSO), the same Pria account is reused. The new social provider becomes an additional sign-in method on top.

This means:

* A user can sign up with email + password, then later sign in with Google using the same email, and land in the same account.
* A user can switch freely between providers as long as the email matches.
* Two different providers returning **different** emails for the same human will produce **two separate Pria accounts**. There is no automatic cross-provider linking.

<Info>The most common cause of "I have two accounts" support tickets is a user signing up first with `alice@gmail.com` (Google) and later with `alice@example.com` (work email). The fix is to merge or change one of the emails.</Info>

***

## Re-authentication and token refresh

For the **sign-in** flow, Pria only needs the user to authenticate once — the resulting JWT is what keeps them signed in. The provider's access token is not used to authorise subsequent Pria API calls.

For **Google services** (Gmail, Drive, Calendar, etc.) Pria stores the access token and refresh token so it can call Google APIs on the user's behalf later. Pria automatically refreshes expired tokens. If the user revokes access at Google (e.g. from their [Google Account → Security → Third-party apps](https://myaccount.google.com/connections) page), Pria detects the next call's `401` and clears the stored token — the user is prompted to re-authorise from their [Google Services profile page](/mdx/user-guide/profile-settings/google-services).

***

## Security considerations

* **CSRF protection** — Pria generates a 32-byte cryptographically random `state` value on every authorise redirect, stores it in the user's session with a 5-minute expiry, and validates it on the callback. State mismatch or expiry produces an `invalid_state` / `state_mismatch` / `state_expired` error.
* **One-time state** — The state value is deleted from the session as soon as the callback reads it, preventing replay attacks.
* **No client secret in the browser** — Token exchange (`code` → `access_token`) is always server-to-server. The provider's client secret is held only in Pria's backend environment.
* **One-time login codes** — After successful social sign-in, the user briefly lands on `/oauth/success`, which completes the session handoff with a short-lived, single-use code that is never written to server logs and is immediately removed from browser history.
* **Mobile flow** — Mobile apps complete the same handoff via a signed deep-link redirect, so sign-in works without relying on browser session cookies surviving the cross-app handoff.

***

## Related

* [Authentication Overview](/mdx/integrations/authentication/overview)
* [Enterprise SSO](/mdx/integrations/authentication/enterprise-sso)
* [Google Workspace integration](/mdx/integrations/google-workspace/overview)
* [Google Services (user guide)](/mdx/user-guide/profile-settings/google-services)
