# How to Disable Authentication for Local Testing in OpenSEO: 3 Steps to Bypass Login

> Easily disable authentication for local testing in OpenSEO. Follow 3 simple steps to bypass login by modifying your .env file and running the dev server. Get started quickly!

- Repository: [Every App/open-seo](https://github.com/every-app/open-seo)
- Tags: how-to-guide
- Published: 2026-09-05

---

**Set `AUTH_MODE=self-hosted` and `BYPASS_EMAIL_VERIFICATION=true` in your `.env` file, then run the dev server to use OpenSEO without any login prompts.**

OpenSEO uses **Better Auth** for user authentication in production, but the codebase includes a dedicated self-hosted mode that streamlines local development. This guide explains exactly how to disable authentication for local testing in OpenSEO using environment-based configuration and the built-in bypass mechanisms in the source code.

## Understanding OpenSEO's Authentication Bypass Architecture

The authentication system in OpenSEO is intentionally modular. When you switch to self-hosted mode, the app automatically uses placeholder values that eliminate external dependencies and skip verification steps.

The bypass logic lives in three key locations:

- **[`src/lib/auth-mode.ts`](https://github.com/every-app/open-seo/blob/main/src/lib/auth-mode.ts)** – Determines whether the app runs in hosted or self-hosted mode
- **[`src/lib/auth.ts`](https://github.com/every-app/open-seo/blob/main/src/lib/auth.ts)** – Configures the Better Auth instance with fallback URLs and optional verification bypass
- **[`src/middleware/ensureUser.ts`](https://github.com/every-app/open-seo/blob/main/src/middleware/ensureUser.ts)** – Enforces sessions (which still work in self-hosted mode without manual login)

In self-hosted mode, the `ensureUser` middleware still receives a valid session from the local auth instance, so protected routes remain functional without requiring you to enter credentials.

## Step 1: Configure Environment Variables for Self-Hosted Mode

Create or edit your `.env` file with these values:

```text

# Run in self-hosted (development) mode

AUTH_MODE=self-hosted

# Any 32-character string satisfies the validation

BETTER_AUTH_SECRET=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

# Optional: skip the email verification step entirely

BYPASS_EMAIL_VERIFICATION=true

```

The `BETTER_AUTH_SECRET` must exist but its value is arbitrary for local testing. The code at [[`src/lib/auth.ts`](https://github.com/every-app/open-seo/blob/main/src/lib/auth.ts)](https://github.com/every-app/open-seo/blob/main/src/lib/auth.ts#L46-L49) handles the rest:

```typescript
const baseUrl = isHostedAuthMode(env.AUTH_MODE) ? getHostedBaseUrl() : "http://localhost";

```

When `AUTH_MODE` is not `"hosted"`, the auth instance falls back to `http://localhost`, eliminating the need for configured callback URLs.

## Step 2: Bypass Email Verification (Optional)

For the fastest possible startup, add `BYPASS_EMAIL_VERIFICATION=true`. This triggers the conditional logic at lines 49-65 in [`src/lib/auth.ts`](https://github.com/every-app/open-seo/blob/main/src/lib/auth.ts):

```typescript
const bypassEmail = Reflect.get(env, "BYPASS_EMAIL_VERIFICATION") === "true";
// ...
emailVerification: bypassEmail ? undefined : { /* verification config */ }

```

When `bypassEmail` evaluates to `true`, the `emailVerification` property is set to `undefined`, removing the verification requirement from the signup flow entirely.

## Step 3: Start the Development Server

Launch the application with your package manager of choice:

```bash
npm run dev

# or

pnpm dev

```

The server initializes the auth instance with:

- **Base URL**: `http://localhost` (placeholder, no external callbacks needed)
- **Email verification**: Disabled (if configured)
- **Session creation**: Automatic for all requests

Navigate to `http://localhost:3000` (or the displayed port). The UI loads immediately without redirecting to a login page. Routes protected by `ensureUser` continue to function because the middleware receives a valid session from the self-hosted auth provider.

## Complete Example: Minimal Local Configuration

Here's a working `.env` configuration for testing OpenSEO without authentication:

```text
AUTH_MODE=self-hosted
BETTER_AUTH_SECRET=local-development-secret-32chars!
BYPASS_EMAIL_VERIFICATION=true

```

With this setup, the following code path executes on every auth initialization:

1. `isHostedAuthMode("self-hosted")` returns `false` ([[`src/lib/auth-mode.ts`](https://github.com/every-app/open-seo/blob/main/src/lib/auth-mode.ts)](https://github.com/every-app/open-seo/blob/main/src/lib/auth-mode.ts))
2. `baseUrl` becomes `"http://localhost"` (lines 46-49 in [`src/lib/auth.ts`](https://github.com/every-app/open-seo/blob/main/src/lib/auth.ts))
3. `emailVerification` becomes `undefined` (lines 49-65, when bypass flag is set)
4. Sessions are created automatically; `ensureUser` middleware passes without manual login

## Advanced: Completely Disable the Auth Middleware

If you need every route to be publicly accessible without any session checks, temporarily modify [[`src/middleware/ensureUser.ts`](https://github.com/every-app/open-seo/blob/main/src/middleware/ensureUser.ts)](https://github.com/every-app/open-seo/blob/main/src/middleware/ensureUser.ts):

```typescript
// Comment out or short-circuit the enforcement logic
export const ensureUser = async (c: Context, next: Next) => {
  // Bypass for complete open access during testing
  return next();
};

```

Revert this change before committing. The environment-based approach is recommended for most local testing scenarios.

## Key Files and Their Roles

| File | Purpose | Lines of Interest |
|:---|:---|:---|
| [`src/lib/auth.ts`](https://github.com/every-app/open-seo/blob/main/src/lib/auth.ts) | Core auth builder with base URL and verification logic | 46-65 |
| [`src/lib/auth-mode.ts`](https://github.com/every-app/open-seo/blob/main/src/lib/auth-mode.ts) | Utility to detect hosted vs. self-hosted mode | Entire file |
| [`src/middleware/ensureUser.ts`](https://github.com/every-app/open-seo/blob/main/src/middleware/ensureUser.ts) | Session enforcement middleware | Entire file |
| `.env.example` | Template showing all supported variables | Entire file |

## Summary

- **Set `AUTH_MODE=self-hosted`** to switch from hosted production mode to local development mode
- **Provide any 32-character `BETTER_AUTH_SECRET`** to satisfy validation requirements
- **Add `BYPASS_EMAIL_VERIFICATION=true`** to eliminate the email verification step
- **Run `npm run dev`** to start a fully functional OpenSEO instance without login prompts
- **The `ensureUser` middleware** receives automatic sessions, so protected routes work seamlessly

## Frequently Asked Questions

### What happens if I omit `BYPASS_EMAIL_VERIFICATION`?

The application runs in self-hosted mode but still configures the email verification flow. You can complete sign-up with any email address, but the verification step will appear in the UI. Set the bypass flag to eliminate this step entirely for faster iteration.

### Can I use a real BETTER_AUTH_SECRET for local testing?

Yes, but it's unnecessary. The secret value is not cryptographically validated for localhost operations; it only needs to meet the 32-character minimum length requirement enforced by Better Auth's configuration.

### Will these settings affect production deployments?

No. Production deployments should use `AUTH_MODE=hosted` with proper `BETTER_AUTH_URL` and `BETTER_AUTH_SECRET` values configured in your hosting environment. The self-hosted mode code paths are explicitly designed for local development only.

### Does disabling authentication remove API rate limiting or other protections?

This configuration only affects the Better Auth authentication layer. Other middleware, database constraints, and application logic remain active. For complete removal of access controls, you would need to modify `ensureUser` and any additional authorization checks throughout the codebase.