# OpenSEO Authentication Modes Explained: Cloudflare, Local Dev, and Hosted SaaS

> Explore OpenSEO authentication modes including Cloudflare Access, local development, and hosted SaaS. Configure production SSO and local dev easily with AUTH_MODE.

- Repository: [Every App/open-seo](https://github.com/every-app/open-seo)
- Tags: deep-dive
- Published: 2026-09-06

---

**OpenSEO supports three authentication modes—`cloudflare_access`, `local_noauth`, and `hosted`—selected at runtime via the `AUTH_MODE` environment variable to handle everything from production SSO to local development.**

OpenSEO, an open-source SEO platform maintained by `every-app/open-seo`, provides flexible authentication strategies to match different deployment scenarios. Understanding these **authentication modes for OpenSEO** ensures you configure the right security model for your environment, whether you're running a managed Cloudflare deployment, a local development instance, or a self-hosted SaaS service.

## The Three OpenSEO Authentication Modes

The [`src/lib/auth-mode.ts`](https://github.com/every-app/open-seo/blob/main/src/lib/auth-mode.ts) file defines the core authentication architecture. Each mode serves a distinct purpose with specific implementation details.

### cloudflare_access: Default Production Mode

**`cloudflare_access`** is the default authentication mode in OpenSEO. It delegates identity verification to **Cloudflare Access** (also known as Cloudflare Zero Trust), which provides managed single sign-on (SSO) through integrated identity providers.

In this mode:
- The UI and all API endpoints are protected by Cloudflare's edge authentication
- Users authenticate through your configured IdP (Google Workspace, Okta, Azure AD, etc.)
- No session management code runs inside the application—Cloudflare handles all credential validation

This mode activates automatically when `AUTH_MODE` is unset or contains an invalid value, as implemented in the `getAuthMode` helper function:

```typescript
// From src/lib/auth-mode.ts - getAuthMode validates and defaults
const authMode = getAuthMode(process.env.AUTH_MODE);
// Returns "cloudflare_access" if AUTH_MODE is missing or invalid

```

### local_noauth: Development-Only Mode

**`local_noauth`** completely disables authentication for rapid local development and CI testing. Every request is accepted without credential checks, streamlining setup when auth infrastructure isn't available.

Use this mode exclusively for:
- Local development environments
- Automated integration tests
- Temporary debugging sessions

Never deploy `local_noauth` to production—the mode intentionally bypasses all security controls.

```typescript
// Example: detecting local mode to skip auth middleware
import { getAuthMode } from "@/lib/auth-mode";

const authMode = getAuthMode(process.env.AUTH_MODE);
if (authMode === "local_noauth") {
  // Bypass authentication checks
  console.warn("Running without authentication - development only");
}

```

### hosted: Full-Featured SaaS Mode

**`hosted`** mode transforms OpenSEO into a multi-tenant SaaS platform with complete user management. It integrates the **better-auth** library with multiple authentication plugins:

| Plugin | Functionality |
|--------|---------------|
| **OAuth** | Social login (Google, GitHub, etc.) |
| **API keys** | Programmatic access with prefixed credentials |
| **Organizations** | Team/workspace isolation and RBAC |
| **Email verification** | Account confirmation workflows |

The [`src/lib/auth-client.ts`](https://github.com/every-app/open-seo/blob/main/src/lib/auth-client.ts) file configures the client-side `authClient` instance with these plugins for the hosted UI:

```typescript
// Client-side authentication setup for hosted mode
import { authClient } from "@/lib/auth-client";

// authClient enables OAuth flows, API key management, and org switching
// in the hosted OpenSEO interface

```

## API Key Authentication in Hosted Mode

Hosted and local modes support **API-key authentication** for programmatic access. Keys follow a strict naming convention defined in [`src/lib/auth-api-key.ts`](https://github.com/every-app/open-seo/blob/main/src/lib/auth-api-key.ts):

```typescript
// API keys must use the "oseo_" prefix
const API_KEY_PREFIX = "oseo_"; // src/lib/auth-api-key.ts#L4

// Example valid key: oseo_live_abc123xyz789

```

This prefix distinguishes API credentials from OAuth tokens when accessing the **MCP (Management Control Plane)** endpoint at [`src/server/mcp/transport.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/transport.ts). The `createApiKeyPlugin` function in [`auth-api-key.ts`](https://github.com/every-app/open-seo/blob/main/auth-api-key.ts) enforces this format during key generation and validation.

## How OpenSEO Selects Authentication Mode at Runtime

The server determines which mode to activate through a straightforward environment-based flow:

1. **`process.env.AUTH_MODE`** is read at startup in [`src/server.ts`](https://github.com/every-app/open-seo/blob/main/src/server.ts)
2. **`getAuthMode`** validates the value against allowed modes (`cloudflare_access`, `local_noauth`, `hosted`)
3. **Invalid or missing values** fall back to `cloudflare_access`
4. **Routing logic** branches based on the resolved mode to apply appropriate middleware

The `isHostedAuthMode()` and `isHostedClientAuthMode()` utilities provide type-safe checks throughout the codebase:

```typescript
// Conditional behavior based on auth mode
import { isHostedClientAuthMode } from "@/lib/auth-mode";

export const isHosted = isHostedClientAuthMode();
// Controls whether login UI renders better-auth components

```

## Configuration Examples

### Cloudflare Access (Production)

```bash

# Minimal configuration - defaults apply

AUTH_MODE=cloudflare_access

# Or omit entirely - this is the default

```

### Local Development

```bash

# Disable all authentication

AUTH_MODE=local_noauth

```

### Self-Hosted SaaS

```bash

# Enable full user management with better-auth

AUTH_MODE=hosted

# Required for hosted mode

BETTER_AUTH_SECRET=your-secret
DATABASE_URL=postgresql://...

```

## Summary

- **OpenSEO provides three authentication modes**: `cloudflare_access` (default/production), `local_noauth` (development), and `hosted` (SaaS)
- **Mode selection** happens at runtime via the `AUTH_MODE` environment variable, validated by `getAuthMode` in [`src/lib/auth-mode.ts`](https://github.com/every-app/open-seo/blob/main/src/lib/auth-mode.ts)
- **API keys** use the mandatory `oseo_` prefix, defined in [`src/lib/auth-api-key.ts`](https://github.com/every-app/open-seo/blob/main/src/lib/auth-api-key.ts)
- **Hosted mode** leverages the better-auth library with plugins for OAuth, organizations, and email verification
- **Default fallback** to `cloudflare_access` ensures production-grade security when configuration is missing

## Frequently Asked Questions

### How do I switch OpenSEO from Cloudflare Access to hosted mode?

Set the `AUTH_MODE=hosted` environment variable before starting the server. The `getAuthMode` function in [`src/lib/auth-mode.ts`](https://github.com/every-app/open-seo/blob/main/src/lib/auth-mode.ts) will validate this value and configure the better-auth client from [`src/lib/auth-client.ts`](https://github.com/every-app/open-seo/blob/main/src/lib/auth-client.ts). You'll also need to configure database credentials and `BETTER_AUTH_SECRET` for hosted mode to function.

### Is local_noauth safe to use in production?

**No.** The `local_noauth` mode intentionally disables all authentication checks and should only be used for local development or CI testing. According to the source code in [`src/lib/auth-mode.ts`](https://github.com/every-app/open-seo/blob/main/src/lib/auth-mode.ts), this mode accepts every request without credential validation, creating a critical security vulnerability in production environments.

### Can I use API keys with Cloudflare Access mode?

API keys are primarily designed for the `hosted` authentication mode where better-auth manages programmatic credentials. While [`src/lib/auth-api-key.ts`](https://github.com/every-app/open-seo/blob/main/src/lib/auth-api-key.ts) defines the `oseo_` prefix structure, Cloudflare Access mode relies entirely on Cloudflare's edge authentication and typically uses service tokens or API tokens managed through the Cloudflare dashboard rather than application-level API keys.

### What identity providers work with cloudflare_access mode?

Any identity provider integrated with **Cloudflare Access** works with OpenSEO's default mode, including Google Workspace, Microsoft Azure AD, Okta, GitHub, and custom SAML/OIDC providers. Because authentication occurs at Cloudflare's edge before requests reach your OpenSEO instance, your specific IdP configuration happens entirely within the Cloudflare Zero Trust dashboard, not in OpenSEO's codebase.