Production OAuth
Production setup guidance for stable Google and GitHub OAuth flows.
rs-auth currently treats Google and GitHub OAuth login as stable for these endpoints:
/auth/login/{provider}/auth/callback/{provider}
Provider setup
For each provider you must configure:
provider_idclient_idclient_secretredirect_url
Supported stable provider IDs are:
googlegithub
Configuration is validated at runtime. Duplicate provider IDs, unsupported providers, empty credentials, and invalid URLs fail fast.
Redirect URIs
Your provider dashboard redirect URI must exactly match the configured redirect_url.
Typical local values:
http://localhost:3000/auth/callback/googlehttp://localhost:3000/auth/callback/github
Typical production values:
https://app.example.com/auth/callback/googlehttps://app.example.com/auth/callback/github
HTTPS and proxies
Use HTTPS in production.
If your app runs behind a reverse proxy:
- terminate TLS at the proxy or load balancer
- preserve the original host and scheme headers
- make sure the externally visible callback URL matches the configured
redirect_url
Cookies
Session cookies are signed and should normally stay:
http_only = truesecure = truesame_site = Lax
If you terminate TLS upstream, keep secure = true in production.
Secret management
Keep these values out of source control:
- cookie signing secret
- OAuth client secrets
- database credentials
Load them from environment variables or your platform secret store.
Account linking tradeoffs
Implicit account linking is enabled by default when a provider returns an email that matches an existing user.
This is practical for first-party apps, but stricter environments may want to disable it and require an explicit linking flow outside the current stable surface.
Explicit linking through /auth/link/{provider} provides more control: users must already be authenticated, and the OAuth account is attached to their existing session without creating a new one. This is useful for multi-factor authentication strategies or when you want to give users control over which providers they link to their account.
Stored data
OAuth account data in accounts includes:
provider_id- provider account ID
- access token
- refresh token if supplied
- access token expiry if supplied
- granted scope if supplied
Transient OAuth state stores:
provider_idcsrf_statepkce_verifierintent- distinguishes login flows from explicit linking flowslink_user_id- user ID when linking to an existing accountexpires_at
OAuth state is one-time-use and cleaned up separately from verification tokens.
Operational cleanup
Run:
rs-auth-cli cleanup --database-url postgres://user:pass@localhost/dbThis removes expired:
- sessions
- verifications
- OAuth state