| 1 | --- |
| 2 | title: Sign-in providers |
| 3 | description: Choose a standalone sign-in walkthrough for your existing Alchemy project. |
| 4 | sidebar: |
| 5 | label: Overview |
| 6 | order: 0 |
| 7 | --- |
| 8 | |
| 9 | Add authentication to an existing Alchemy project with one of the walkthroughs below. Each page introduces its own files; you do not need to copy an application from this overview or complete another provider guide first. |
| 10 | |
| 11 | ## Choose a sign-in method |
| 12 | |
| 13 | - [Email and password](/better-auth/sign-in-providers/email-password): D1-backed registration, real email delivery through Resend, verification, and password recovery. |
| 14 | - [GitHub](/better-auth/sign-in-providers/github): an OAuth App with minimal profile and email scopes. |
| 15 | - [Google](/better-auth/sign-in-providers/google): a web OAuth client, consent-screen audience, and test users. |
| 16 | - [Microsoft](/better-auth/sign-in-providers/microsoft): an Entra registration with an explicit tenant. |
| 17 | - [Custom OAuth and OIDC](/better-auth/sign-in-providers/custom-oauth): a Keycloak client using discovery and ID-token verification. |
| 18 | |
| 19 | ## Understand Alchemy's role |
| 20 | |
| 21 | The Auth service passes options directly to `BetterAuth`, reading server configuration through Effect `Config`. Its host supplies the database layer and forwards auth requests; Alchemy provisions the stable signing secret and runs supported database migrations automatically. |
| 22 | |
| 23 | The walkthroughs use a Cloudflare Worker and D1 with a [configured Cloudflare profile](/cloudflare/setup). Keep your Alchemy integration versions aligned and preserve the stack's state across deployments. |
| 24 | |
| 25 | ## Keep the browser separate |
| 26 | |
| 27 | The browser uses `createAuthClient` from `better-auth/client`, not the server's Auth service. With the page and API on the same origin, the client uses `/api/auth` and Better Auth manages session cookies; private application endpoints must still check the session and authorization on the server. |
| 28 | |
| 29 | ## Choose the actual origin |
| 30 | |
| 31 | Alchemy prints the development URL instead of requiring a fixed port. Use that actual origin wherever a provider requires a registered callback, and set `AUTH_BASE_URL` to the real HTTPS Worker origin in production, without a trailing slash or `/api/auth`. |
| 32 | |
| 33 | Setting `AUTH_BASE_URL` does not attach a domain or provision DNS. Keep the page and API on the same origin for these examples; a cross-origin application additionally needs explicit trusted origins, credentialed CORS, and an appropriate cookie policy—not disabled origin or CSRF checks. |
| 34 | |
| 35 | ## Distinguish the two redirects |
| 36 | |
| 37 | A provider's redirect URI, such as `https://auth.example.com/api/auth/callback/github`, receives the authorization code on the server. The browser's `callbackURL`, such as `/`, selects the application page after success; email/password does not require an OAuth callback registration. |
| 38 | |
| 39 | Better Auth handles state, PKCE, code exchange, and session cookies. Leave callback failures on its built-in `/api/auth/error` page rather than adding a custom callback handler or an application error-query convention. |
| 40 | |
| 41 | ## Keep credentials server-only |
| 42 | |
| 43 | Read public provider identifiers with `Config.String` and secrets with `Config.Redacted` during service construction. Use separate production credentials, keep environment files out of source control, and never put secrets in `VITE_*`, browser bundles, or logs—including token-bearing callback URLs. |
| 44 | |
| 45 | ## Combine methods deliberately |
| 46 | |
| 47 | When adding another method, retain one Auth service, database, and session cookie; preserve the existing mail hooks and plugins, and add built-in OAuth providers to the same `socialProviders` object. Follow Better Auth's [account-linking guidance](https://www.better-auth.com/docs/concepts/users-accounts#account-linking) rather than merging users solely because their email addresses match. |