Ploy
Ploy
Authentication

Social sign-in

Let users sign in with Google, Apple, or GitHub.

Social sign-in

Ploy Auth supports Google, Apple, and GitHub. You bring your own OAuth credentials, so the consent screen shows your app's name and users' accounts belong to you.

Set up a provider

  1. Create OAuth credentials with the provider (below).

  2. Register the callback URL for every domain users sign in from:

    https://<your-domain>/_ploy/auth/callback/<provider>

    The dashboard shows it for your project's production URL. Add the same path for each custom domain and any preview URL you want to sign in on.

  3. In the dashboard, open Auth → Settings, enter the credentials under the provider, turn it on, and click Save settings.

The provider appears in GET /_ploy/auth/config and in the SignInForm and SignUpForm components right away.

Google

  1. In Google Cloud Console, open APIs & Services → Credentials and create an OAuth client ID of type Web application.
  2. Add the callback URL under Authorized redirect URIs.
  3. Copy the Client ID and Client secret into Ploy.

Ploy requests the openid email profile scopes and uses PKCE.

GitHub

  1. In GitHub, open Settings → Developer settings → OAuth Apps → New OAuth App.
  2. Set Authorization callback URL to the callback URL.
  3. Generate a client secret and copy the Client ID and secret into Ploy.

Ploy requests read:user user:email and uses the account's primary verified email. GitHub accounts without a verified email cannot sign in.

Apple

Sign in with Apple needs a paid Apple Developer account.

  1. Under Certificates, Identifiers & Profiles, create an App ID with Sign in with Apple enabled.
  2. Create a Services ID, enable Sign in with Apple, and add your domain and the callback URL as a return URL. Apple requires HTTPS.
  3. Under Keys, create a key with Sign in with Apple enabled and download the .p8 file.
  4. In Ploy, enter:
FieldValue
Services IDThe Services ID identifier, e.g. com.example.web
Team IDYour 10-character Apple Developer team ID
Key IDThe key's 10-character ID
Private key (.p8)The full contents of the .p8 file

Ploy signs a short-lived client secret with the key on every sign-in, so there is nothing to rotate every six months. Apple sends the user's name only on their first sign-in; Ploy stores it in metadata.name when it creates the account. Users who choose Hide My Email get a private relay address.

The private key and client secrets are encrypted at rest and never returned by the API. To rotate one, paste the new value and save.

Start sign-in

With @meetploy/auth-react, enabled providers show up in SignInForm and SignUpForm automatically, or call signInWithProvider:

const { signInWithProvider } = useAuth();

<button
	onClick={() => signInWithProvider("github", { redirectTo: "/dashboard" })}
>
	Continue with GitHub
</button>;

Without React, navigate to the endpoint:

window.location.href =
	"/_ploy/auth/oauth/github?redirectTo=" + encodeURIComponent("/dashboard");

Errors

When sign-in does not complete, the user is sent back to redirectTo with a ploy_auth_error parameter. useAuth().redirectError exposes it and removes it from the URL.

CodeMeaning
access_deniedThe user cancelled at the provider
account_existsAn account with this email exists and the provider did not verify the email
email_requiredThe provider did not share a verified email address
signups_disabledNo account exists for this identity and sign-ups are off
invalid_stateThe sign-in attempt expired (after 10 minutes) or was tampered with
provider_disabledThe provider was turned off during sign-in
rate_limitedToo many attempts from this IP
oauth_failedThe provider rejected the code exchange

Account linking

Ploy keeps one user per email address and links provider identities to it:

  1. A returning identity (same provider and provider user ID) signs in to the user it is linked to, even if the email at the provider changed.
  2. If the user is already signed in, the new identity is linked to their account.
  3. If the provider reports a verified email that matches an existing user, the identity is linked to that user.
  4. Otherwise a new user is created, if sign-ups are allowed.

A provider email that is not verified is never linked to an existing account.

Takeover protection. Ploy does not verify emails for password and passkey sign-ups, so anyone could register an address they don't own. When a verified provider identity links to such an unverified account, Ploy first removes its password and passkeys and revokes its sessions, then marks the email verified. The owner of the email keeps the account; whoever registered it without owning it loses access.

Local development

ploy dev reads provider credentials from your project's .env. A provider is enabled when all its variables are set:

.env
PLOY_AUTH_GOOGLE_CLIENT_ID=...
PLOY_AUTH_GOOGLE_CLIENT_SECRET=...

PLOY_AUTH_GITHUB_CLIENT_ID=...
PLOY_AUTH_GITHUB_CLIENT_SECRET=...

PLOY_AUTH_APPLE_CLIENT_ID=...
PLOY_AUTH_APPLE_TEAM_ID=...
PLOY_AUTH_APPLE_KEY_ID=...
PLOY_AUTH_APPLE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"

Register http://localhost:<port>/_ploy/auth/callback/<provider> with the provider, where <port> is your dev server's port. Google and GitHub accept localhost callbacks; Apple only accepts HTTPS, so test Apple on a deployment.

How is this guide?

Last updated on