Social sign-in (OAuth)

"Continue with Google / GitHub / …" for your app's users. This is an operator guide: providers are configured with environment variables, so a provider lights up only once its credentials are supplied.

This page is for whoever runs the platform. App developers trigger the flow with signInWithOAuth({ provider }) in the SDK; the wire endpoints are on the Authentication page. No provider is enabled by default.

How it works

Kethosbase acts as a confidential OAuth2/OIDC client. When a user starts sign-in, the browser is sent to the provider; the provider redirects back to the project's callback with an authorization code; the platform exchanges that code for tokens server-to-server, reads the user's profile, and mints a normal session. The code and provider tokens never travel through the browser.

Enable a provider

Providers are read from the environment of the data-API service. List the ones you want in KETHOSBASE_OAUTH_PROVIDERS (comma-separated), then set each provider's client id and secret. The variable name embeds the provider name in upper case:

KETHOSBASE_OAUTH_PROVIDERS=google,github

KETHOSBASE_OAUTH_GOOGLE_CLIENT_ID=…
KETHOSBASE_OAUTH_GOOGLE_CLIENT_SECRET=…

KETHOSBASE_OAUTH_GITHUB_CLIENT_ID=…
KETHOSBASE_OAUTH_GITHUB_CLIENT_SECRET=…

Google, GitHub, and GitLab ship as presets — their authorization, token, and userinfo endpoints and default scopes are built in, so you supply only the id and secret. A provider missing its id or secret stays disabled; the rest keep working.

Generic OIDC providers

Any other provider works by giving the endpoints yourself. Add its name to the list and set the URLs (plus, if the userinfo response names them differently, which JSON fields carry the e-mail and the stable user id):

KETHOSBASE_OAUTH_PROVIDERS=acme

KETHOSBASE_OAUTH_ACME_CLIENT_ID=…
KETHOSBASE_OAUTH_ACME_CLIENT_SECRET=…
KETHOSBASE_OAUTH_ACME_AUTH_URL=https://id.acme.com/authorize
KETHOSBASE_OAUTH_ACME_TOKEN_URL=https://id.acme.com/token
KETHOSBASE_OAUTH_ACME_USERINFO_URL=https://id.acme.com/userinfo
KETHOSBASE_OAUTH_ACME_SCOPES=openid email
KETHOSBASE_OAUTH_ACME_EMAIL_FIELD=email
KETHOSBASE_OAUTH_ACME_ID_FIELD=sub
Variable (per provider X)Meaning
KETHOSBASE_OAUTH_X_CLIENT_IDOAuth client id. Required.
KETHOSBASE_OAUTH_X_CLIENT_SECRETOAuth client secret. Required.
KETHOSBASE_OAUTH_X_AUTH_URLAuthorization endpoint. Preset for Google/GitHub/GitLab.
KETHOSBASE_OAUTH_X_TOKEN_URLToken endpoint.
KETHOSBASE_OAUTH_X_USERINFO_URLUserinfo / profile endpoint.
KETHOSBASE_OAUTH_X_SCOPESSpace-separated scopes.
KETHOSBASE_OAUTH_X_EMAIL_FIELDUserinfo JSON key holding the e-mail (default email).
KETHOSBASE_OAUTH_X_EMAIL_VERIFIED_FIELDUserinfo JSON key holding the verified flag (default email_verified).
KETHOSBASE_OAUTH_X_ID_FIELDUserinfo JSON key holding the stable id (default sub).

For a preset provider these URL/field variables are optional overrides; a generic provider needs the three URLs, or it stays disabled.

To let a provider's users link onto an existing account by e-mail, the provider must assert the address is verified (email_verified). A provider that returns an unverified e-mail can still create new accounts, but a collision with an existing address is refused (error=provider_email_unverified) — so an unverified address can never take over an account.

Register the callback URL

In the provider's console, add this project's callback as an authorized redirect URI:

https://<project-ref>.kethosbase.com/auth/v1/callback

The same path serves every provider for that project. Register one callback per project ref you enable sign-in on.

Set the redirect allowlist

After sign-in the browser lands back in your app with the session in the URL. To prevent an attacker from redirecting that session to their own site, each project keeps an allowlist — the same one the magic link uses:

Both are set per project from the project's dashboard settings. Until at least the site URL is configured the flow has nowhere safe to land, so sign-in won't complete — this is default-deny by design. A target that isn't allowlisted is refused with 400 bad_redirect, checked both when the flow starts and again at the callback.

What a user sees

An existing account with the same provider identity signs straight in. On a first social sign-in the platform links by e-mail — matching an existing account with that address, or creating one — and records the provider identity so the next sign-in maps to the same user.

Notes & limitations