Social Login
Google and GitHub sign-in, hosted by Camel Accounts. Providers activate only when their credentials are configured server-side — an unconfigured provider behaves as if it doesn't exist.
Discover enabled providers
Public endpoint (no auth):
curl -s "$ISSUER/auth/social/providers"{ "success": true, "data": { "providers": ["github", "google"] } }Use this to decide which buttons your UI shows.
The browser flow
Both endpoints are browser redirects — never call them with fetch/XHR:
① Your button → GET $ISSUER/auth/social/google/begin?next=/somewhere
② 302 to Google's consent screen (state bound in Redis, single-use, 10 min TTL)
③ Google → GET $ISSUER/auth/social/google/callback?code=…&state=…
④ Camel Accounts exchanges the code, applies linking rules,
sets camel_session, then 302s back to `next`| Provider | Scopes requested from provider |
|---|---|
openid email profile | |
| GitHub | read:user user:email |
The optional next query parameter controls the post-login landing path; it is sanitized to same-origin relative paths (protocol-relative //, backslashes, and foreign origins fall back to /).
Rate limit: 10/min/IP on /begin.
Linking rules (important)
These rules are fail-closed — there is no silent merging, ever:
- New user at the provider → account created automatically; email pre-marked verified iff the provider says it's verified; no password exists (unguessable placeholder hash).
- Existing local account with matching verified email → provider signs in into that account (linked).
- Existing local account whose email matches but was never verified → refused: redirect carries
error=social_email_taken. This blocks takeover-by-unverified-email. - GitHub users without any accessible primary email →
error=social_no_email.
Every social login lands in security events like any other sign-in.
Callback failure modes
All failures redirect the browser to /login?error=<reason> — you'll never see JSON here. Handle these reasons in whatever renders that page:
error value | Meaning |
|---|---|
social_denied | User declined at the provider |
social_expired | State missing/expired/replayed (took >10 min or double-loaded) |
social_email_taken | Email collision with an unverified local account |
social_no_email | Provider gave no usable email |
social_unknown_provider | Provider not configured/disabled |
social_failed | Generic exchange failure |
Unknown/unconfigured providers also answer a direct /begin hit with a 404 envelope (social login provider not available).
Testing locally
Social callbacks must reach your dev box: set SOCIAL_REDIRECT_BASE=http://localhost:8080 on the Camel Accounts deployment and register the resulting callback URLs with each provider console:
{SOCIAL_REDIRECT_BASE}/auth/social/google/callback
{SOCIAL_REDIRECT_BASE}/auth/social/github/callbackButtons appear automatically once both halves of a provider's credentials exist in the environment.