OAuth Providers
Configure third-party OAuth and social login providers (Google, GitHub, Microsoft, etc.) for self-hosted HelloJohn.
OAuth Providers
HelloJohn supports OAuth 2.0 / OIDC social login with popular providers. This page covers how to create OAuth apps with each provider and configure them in HelloJohn.
How Social Login Works
- User clicks "Sign in with Google" (or any provider)
- HelloJohn redirects to the provider's authorization URL
- User authenticates with the provider
- Provider redirects back to HelloJohn with an authorization code
- HelloJohn exchanges the code for tokens and fetches the user's profile
- HelloJohn creates or links the user account, issues a session
Callback URL
When registering your app with an OAuth provider, use this callback URL:
https://your-hellojohn-domain.com/v1/oauth/callback/{provider}Examples:
https://auth.example.com/v1/oauth/callback/google
https://auth.example.com/v1/oauth/callback/github
https://auth.example.com/v1/oauth/callback/microsoftConfiguring Providers
Set provider credentials as environment variables. You can also configure them via the Admin API or dashboard.
- Go to Google Cloud Console → APIs & Services → Credentials
- Create an OAuth 2.0 Client ID (Web application)
- Add your callback URL to Authorized redirect URIs
- Copy the Client ID and Client Secret
HELLOJOHN_OAUTH_GOOGLE_CLIENT_ID=your_google_client_id.apps.googleusercontent.com
HELLOJOHN_OAUTH_GOOGLE_CLIENT_SECRET=GOCSPX-your_client_secret
HELLOJOHN_OAUTH_GOOGLE_ENABLED=trueScopes requested: openid email profile
GitHub
- Go to GitHub Developer Settings → OAuth Apps → New OAuth App
- Set Authorization callback URL to your HelloJohn callback URL
- Copy the Client ID and generate a Client Secret
HELLOJOHN_OAUTH_GITHUB_CLIENT_ID=Ov23liYourClientId
HELLOJOHN_OAUTH_GITHUB_CLIENT_SECRET=your_github_client_secret
HELLOJOHN_OAUTH_GITHUB_ENABLED=trueScopes requested: read:user user:email
GitHub users may have private emails. HelloJohn fetches the primary email via the
/user/emailsendpoint automatically.
Microsoft / Azure AD
- Go to Azure Portal → Azure Active Directory → App registrations → New registration
- Set Redirect URI (Web) to your callback URL
- Under Certificates & secrets, create a Client Secret
- Copy the Application (client) ID and Directory (tenant) ID
HELLOJOHN_OAUTH_MICROSOFT_CLIENT_ID=your_application_client_id
HELLOJOHN_OAUTH_MICROSOFT_CLIENT_SECRET=your_client_secret_value
HELLOJOHN_OAUTH_MICROSOFT_TENANT_ID=common # or your specific tenant ID
HELLOJOHN_OAUTH_MICROSOFT_ENABLED=trueSet TENANT_ID to common to allow any Microsoft account, or to a specific Azure AD tenant ID to restrict to your organization.
Scopes requested: openid email profile
Apple
Apple requires additional setup — you need an Apple Developer account.
- Create an App ID with Sign in with Apple capability
- Create a Service ID (this is your OAuth client)
- Generate a private key (
.p8file) — download it once - Configure your domain and callback URLs in the Service ID
HELLOJOHN_OAUTH_APPLE_CLIENT_ID=com.example.your.service.id
HELLOJOHN_OAUTH_APPLE_TEAM_ID=YOURTEAMID
HELLOJOHN_OAUTH_APPLE_KEY_ID=YOURKEYID
HELLOJOHN_OAUTH_APPLE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n..."
HELLOJOHN_OAUTH_APPLE_ENABLED=trueThe private key is the content of the .p8 file. Use \n for line breaks when setting as an environment variable.
Apple does not return the user's name or email after the first sign-in. HelloJohn stores this on first sign-in and uses it for subsequent logins.
Discord
- Go to Discord Developer Portal → New Application
- Under OAuth2, add your callback URL to Redirects
- Copy the Client ID and Client Secret
HELLOJOHN_OAUTH_DISCORD_CLIENT_ID=your_discord_client_id
HELLOJOHN_OAUTH_DISCORD_CLIENT_SECRET=your_discord_client_secret
HELLOJOHN_OAUTH_DISCORD_ENABLED=trueScopes requested: identify email
- Go to LinkedIn Developer Portal → Create App
- Under Auth, add your callback URL to Authorized redirect URLs
- Copy the Client ID and Client Secret
HELLOJOHN_OAUTH_LINKEDIN_CLIENT_ID=your_linkedin_client_id
HELLOJOHN_OAUTH_LINKEDIN_CLIENT_SECRET=your_linkedin_client_secret
HELLOJOHN_OAUTH_LINKEDIN_ENABLED=trueScopes requested: openid profile email
Configuring via Admin API
Alternatively, configure providers via the Admin API (useful for multi-tenant setups where each tenant has different OAuth apps):
curl -X PUT "https://api.hellojohn.dev/v1/admin/oauth/providers/google" \
-H "Authorization: Bearer sk_live_abc123" \
-H "X-Tenant-ID: tnt_01HABCDEF654321" \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"client_id": "your_google_client_id.apps.googleusercontent.com",
"client_secret": "GOCSPX-your_client_secret"
}'Account Linking
When a user signs in with OAuth and the provider email matches an existing account:
| Scenario | Default Behavior |
|---|---|
| New user, new email | Create new account |
| Existing email, same provider | Sign in to existing account |
| Existing email, different provider | Link to existing account (configurable) |
Configure linking behavior:
# Allow linking different OAuth providers to the same account
HELLOJOHN_OAUTH_AUTO_LINK=true
# Require explicit link confirmation (more secure)
HELLOJOHN_OAUTH_AUTO_LINK=falseAllowed Email Domains
Restrict social login to specific email domains (e.g., company SSO):
curl -X PATCH "https://api.hellojohn.dev/v1/admin/config" \
-H "Authorization: Bearer sk_live_abc123" \
-H "X-Tenant-ID: tnt_01HABCDEF654321" \
-H "Content-Type: application/json" \
-d '{
"oauth_allowed_domains": ["example.com", "example.org"]
}'Users signing in with OAuth emails outside these domains will receive an error.
Frontend Integration
Use the React SDK to add social login buttons:
import { useAuth } from "@hellojohn/react";
function SocialLogin() {
const { signInWithOAuth } = useAuth();
return (
<div>
<button onClick={() => signInWithOAuth({ provider: "google" })}>
Sign in with Google
</button>
<button onClick={() => signInWithOAuth({ provider: "github" })}>
Sign in with GitHub
</button>
<button onClick={() => signInWithOAuth({ provider: "microsoft" })}>
Sign in with Microsoft
</button>
</div>
);
}signInWithOAuth redirects to the provider and returns when the flow completes.
Accessing OAuth Profile Data
After sign-in, the user's connected OAuth profile is available:
const { user } = useUser();
// List all connected OAuth providers
const connections = user.oauthConnections;
// [{ provider: "google", provider_user_id: "...", email: "..." }]On the backend:
curl "https://api.hellojohn.dev/v1/users/usr_01HABCDEF123456/oauth-connections" \
-H "Authorization: Bearer sk_live_abc123" \
-H "X-Tenant-ID: tnt_01HABCDEF654321"Troubleshooting
redirect_uri_mismatch
The callback URL registered in the provider does not match what HelloJohn is sending. Verify:
- The callback URL in the provider console exactly matches:
https://your-domain.com/v1/oauth/callback/{provider} - No trailing slashes
- The scheme is
https://(nothttp://)
invalid_client
Client ID or Client Secret is incorrect. Regenerate and update your environment variables.
User gets email_not_provided
Some providers require additional scopes or settings to share the email address:
- GitHub: Users with private emails must grant email access
- Twitter/X: Email is gated behind Elevated API Access
- Discord: Ensure the
emailscope is requested
Apple Sign-in fails locally
Apple requires HTTPS and a real domain. Use a tunnel like ngrok or Cloudflare Tunnel for local development.