# How to Configure Google OAuth Credentials for Production Deployment

> Securely configure Google OAuth credentials for production deployment with Cloudflare Workers. Learn to store secrets, set redirect URIs, and access credentials at runtime for seamless authentication.

- Repository: [Muhammad Arifin/fullstack-next-cloudflare](https://github.com/ifindev/fullstack-next-cloudflare)
- Tags: how-to-guide
- Published: 2026-03-03

---

**Store your Google client ID and secret as encrypted Cloudflare Worker secrets, set the authorized redirect URI to `https://<your-worker>.workers.dev/api/auth/callback/google`, and ensure [`src/modules/auth/utils/auth-utils.ts`](https://github.com/ifindev/fullstack-next-cloudflare/blob/main/src/modules/auth/utils/auth-utils.ts) reads the credentials from `getCloudflareContext().env` at runtime.**

The ifindev/fullstack-next-cloudflare repository provides a production-ready Next.js template that authenticates users via Better Auth and deploys to Cloudflare Workers. When you configure Google OAuth credentials for production deployment, you must inject sensitive values as secure Worker secrets rather than environment variables or committed configuration files. This guide walks through the exact implementation details found in the source code to ensure your authentication flow works securely in production.

## Architecture Overview

The authentication system relies on Better Auth's Google provider running inside a Cloudflare Worker. The flow works as follows:

1. **Provider initialization**: In [`src/modules/auth/utils/auth-utils.ts`](https://github.com/ifindev/fullstack-next-cloudflare/blob/main/src/modules/auth/utils/auth-utils.ts), the `betterAuth()` instance constructs the Google provider using `env.GOOGLE_CLIENT_ID` and `env.GOOGLE_CLIENT_SECRET`.
2. **Runtime injection**: The `env` object comes from `getCloudflareContext()`, which supplies secrets injected by the Cloudflare platform.
3. **OAuth callback**: Google redirects authenticated users to `https://<your-worker-subdomain>.workers.dev/api/auth/callback/google`.
4. **Session establishment**: Better Auth validates the OAuth response against the stored secrets and creates an authenticated session cookie.

Because the credentials are loaded from Cloudflare's secure environment at runtime, they never appear in your source code, build output, or client-side bundles.

## Prerequisites: Create Google OAuth Credentials

Before configuring the production environment, create OAuth 2.0 credentials in the Google Cloud Console:

1. Navigate to the Google Cloud Console and select your project.
2. Enable the Google+ API or configure the OAuth consent screen for external users.
3. Create an **OAuth client ID** of type **Web application**.
4. Add the production callback URL to the authorized redirect URIs list: `https://<your-worker-subdomain>.workers.dev/api/auth/callback/google`.

Replace `<your-worker-subdomain>` with the actual subdomain assigned to your Cloudflare Worker.

## Configuration Steps

### Local Development with .dev.vars

For local testing, the template uses a `.dev.vars` file to simulate Cloudflare secrets. Copy the example file and add your development credentials:

```bash

# .dev.vars

GOOGLE_CLIENT_ID=your-google-client-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your-google-client-secret

```

The `wrangler` CLI automatically loads these values into the local Cloudflare runtime environment when running `pnpm run dev`.

### Production Secrets on Cloudflare

In production, add the credentials as encrypted Cloudflare Worker secrets using the Wrangler CLI:

```bash
wrangler secret put GOOGLE_CLIENT_ID

# Paste your production client ID when prompted

wrangler secret put GOOGLE_CLIENT_SECRET

# Paste your production client secret when prompted

```

Alternatively, if using the GitHub Actions workflow for continuous deployment, add `GOOGLE_CLIENT_ID` and `GOOGLE_CLIENT_SECRET` to your repository's **Secrets and Variables** settings under **Actions secrets**. The workflow defined in [`.github/workflows/deploy.yml`](https://github.com/ifindev/fullstack-next-cloudflare/blob/main/.github/workflows/deploy.yml) (lines 41-44) automatically injects these values during deployment:

```yaml

# .github/workflows/deploy.yml (excerpt)

- name: Deploy to Production
  env:
    GOOGLE_CLIENT_ID: ${{ secrets.GOOGLE_CLIENT_ID }}
    GOOGLE_CLIENT_SECRET: ${{ secrets.GOOGLE_CLIENT_SECRET }}
  run: pnpm run deploy

```

## Verify the Auth Provider Configuration

Ensure the Better Auth configuration correctly references the environment variables. In [`src/modules/auth/utils/auth-utils.ts`](https://github.com/ifindev/fullstack-next-cloudflare/blob/main/src/modules/auth/utils/auth-utils.ts) (lines 34-38), the Google provider configuration appears as follows:

```typescript
// src/modules/auth/utils/auth-utils.ts
socialProviders: {
  google: {
    enabled: true,
    clientId: env.GOOGLE_CLIENT_ID!,
    clientSecret: env.GOOGLE_CLIENT_SECRET!,
  },
},

```

The `cachedAuth` utility in this file ensures the auth instance is built once at module load time, efficiently reusing the configuration across requests while securely accessing the injected secrets via the Cloudflare context.

## Deploy to Production

Once secrets are configured and the redirect URI is set in the Google Cloud Console, deploy your application using one of the following methods:

**Option A: GitHub Actions**
Push to the `main` branch. The workflow in [`.github/workflows/deploy.yml`](https://github.com/ifindev/fullstack-next-cloudflare/blob/main/.github/workflows/deploy.yml) automatically deploys to Cloudflare Workers using the repository secrets you configured.

**Option B: Manual Deployment**
Run the deployment command locally:

```bash
pnpm run deploy

```

Wrangler packages your application and deploys it to the Cloudflare Workers platform, where the runtime accesses the secrets via `getCloudflareContext().env`.

## Summary

- **Cloudflare Workers** store sensitive credentials as encrypted secrets accessible via `wrangler secret put` or GitHub Actions secrets, not in `.env` files.
- **Better Auth** configuration in [`src/modules/auth/utils/auth-utils.ts`](https://github.com/ifindev/fullstack-next-cloudflare/blob/main/src/modules/auth/utils/auth-utils.ts) reads `GOOGLE_CLIENT_ID` and `GOOGLE_CLIENT_SECRET` from `getCloudflareContext().env` at runtime.
- **Authorized redirect URIs** in Google Cloud Console must exactly match the deployed worker URL: `https://<subdomain>.workers.dev/api/auth/callback/google`.
- **Local development** uses `.dev.vars` (based on `.dev.vars.example`) to simulate the Cloudflare runtime environment.

## Frequently Asked Questions

### Where do I store Google OAuth credentials in a Cloudflare Workers environment?

Store them as Cloudflare Worker secrets using the commands `wrangler secret put GOOGLE_CLIENT_ID` and `wrangler secret put GOOGLE_CLIENT_SECRET`. These values are encrypted at rest and only available to your specific Worker at runtime through `getCloudflareContext().env`, unlike standard environment variables which appear in plaintext in the dashboard.

### What callback URL should I configure in the Google Cloud Console?

Use `https://<your-worker-subdomain>.workers.dev/api/auth/callback/google`. You must add this exact URL to the authorized redirect URIs list in your Google OAuth 2.0 client configuration. Any mismatch between this URL and your actual deployment domain will result in redirect_uri_mismatch errors during authentication.

### How does the application access these credentials in the source code?

The application accesses credentials through the Cloudflare runtime context. In [`src/modules/auth/utils/auth-utils.ts`](https://github.com/ifindev/fullstack-next-cloudflare/blob/main/src/modules/auth/utils/auth-utils.ts), the Better Auth configuration references `env.GOOGLE_CLIENT_ID!` and `env.GOOGLE_CLIENT_SECRET!` where `env` is provided by `getCloudflareContext()`. This object contains the secrets injected by the Cloudflare platform, making them available to the Google provider configuration.

### Can I use a standard `.env` file for production deployment?

No. Cloudflare Workers do not read from `.env` files in production. While `.dev.vars` works for local development with `wrangler dev`, production deployments require secrets to be uploaded via the Wrangler CLI or set through the Cloudflare dashboard. This ensures credentials remain encrypted and are never exposed in deployment logs or source control.