# OpenSEO Authentication Modes: Configuring Cloudflare Access, Local, and Hosted Auth

> Explore OpenSEO authentication modes like Cloudflare Access, local, and hosted. Configure easily using the AUTH_MODE environment variable for secure access.

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

---

**OpenSEO supports three authentication modes—`cloudflare_access` for Cloudflare Zero-Trust, `local_noauth` for development, and `hosted` for the managed SaaS platform—configured exclusively via the `AUTH_MODE` environment variable.**

OpenSEO, the open-source SEO platform from every-app/open-seo, implements a flexible authentication architecture that adapts to different deployment environments without code changes. The system determines which authentication strategy to apply at runtime through the `Auth_MODE` environment variable, enabling the same codebase to operate as a secure SaaS application, a Cloudflare-protected self-hosted instance, or a credential-free local development server.

## The Three OpenSEO Authentication Modes

OpenSEO determines user identity and authorization scope through the `AuthMode` type defined in [`src/lib/auth-mode.ts`](https://github.com/every-app/open-seo/blob/main/src/lib/auth-mode.ts). Each mode handles request validation differently based on your infrastructure requirements.

### cloudflare_access (Self-Hosted with Zero-Trust)

Use `cloudflare_access` when deploying a self-hosted instance that relies on **Cloudflare Access** for identity management. In this mode, Cloudflare Access injects an `Authorization` header containing a signed JWT into each request. The OpenSEO server validates this token and extracts the user's identity and permission scopes. This approach delegates all authentication decisions to Cloudflare's edge network, making it ideal for internal tools or teams already using Cloudflare Zero-Trust.

### local_noauth (Local Development)

Set `AUTH_MODE` to `local_noauth` for local development or testing scenarios where authentication must be bypassed. When active, OpenSEO treats all incoming requests as originating from an internal admin user, requiring no authentication headers. This mode eliminates the need to configure external identity providers during rapid prototyping, though it should never be used in production environments.

### hosted (Managed SaaS Platform)

The `hosted` mode powers the official SaaS version of OpenSEO running on Every App's managed platform. Users authenticate through the hosted UI via an OAuth flow managed by the platform. The server reads the session cookie or JWT that the platform sets on each request, automatically authorizing users without additional configuration. This mode is the default for the managed service and handles multi-tenant user isolation.

## Configuring the AUTH_MODE Environment Variable

Authentication mode selection happens at runtime through environment variable configuration. No code changes or rebuilds are required to switch between modes.

Set the variable in your deployment environment:

```bash

# Self-hosted with Cloudflare Access

AUTH_MODE=cloudflare_access

# Local development (no auth)

AUTH_MODE=local_noauth

# Hosted SaaS (managed platform)

AUTH_MODE=hosted

```

For `cloudflare_access` deployments, you must additionally configure a Cloudflare Access Application and define the required authentication policies in your Cloudflare dashboard. The `local_noauth` mode requires no external setup, while `hosted` mode requires deployment to the Every App platform infrastructure. Verify the active mode at runtime using the `/api/oauth/consent` endpoint or the `whoami` tool available in the MCP transport layer.

## Implementing Auth Mode Checks in Code

The core library provides type-safe utilities to branch logic based on the active authentication strategy. All helpers reside in [`src/lib/auth-mode.ts`](https://github.com/every-app/open-seo/blob/main/src/lib/auth-mode.ts).

### Resolving the Current Mode

Use `getAuthMode` to parse and normalize the environment variable value. This function accepts either `process.env.AUTH_MODE` on the server or `import.meta.env.AUTH_MODE` in client bundles:

```typescript
import { getAuthMode } from "@/lib/auth-mode";

export async function handler(request: Request) {
  const authMode = getAuthMode(process.env.AUTH_MODE);
  console.log("Running in auth mode:", authMode);
  // Branch logic based on authMode value
}

```

### Using Predicate Functions

Helper predicates simplify conditional logic without hardcoding string comparisons:

```typescript
import { getAuthMode, isHostedAuthMode, isHostedClientAuthMode, isEmailVerificationBypassed } from "@/lib/auth-mode";

const mode = getAuthMode(import.meta.env.AUTH_MODE);

if (isHostedAuthMode(mode)) {
  // Execute hosted SaaS specific logic
}

if (isEmailVerificationBypassed()) {
  // Skip verification steps in local development
}

if (isHostedClientAuthMode()) {
  // Client-side safeguard ensuring build-time AUTH_MODE matches runtime
}

```

### Server-Side Route Protection

The middleware layer uses these checks to enforce authentication requirements. In [`src/middleware/ensure-user/resolve.ts`](https://github.com/every-app/open-seo/blob/main/src/middleware/ensure-user/resolve.ts), the system uses the auth mode to decide whether to enforce user authentication for a given request. Similarly, [`src/server.ts`](https://github.com/every-app/open-seo/blob/main/src/server.ts) reads `AUTH_MODE` at startup to select the appropriate request-handling path for hosted versus self-hosted deployments.

## Core Files Handling Authentication Logic

Understanding the source file organization helps when customizing authentication behavior:

- **[`src/lib/auth-mode.ts`](https://github.com/every-app/open-seo/blob/main/src/lib/auth-mode.ts)** — Defines the `AuthMode` union type, the `getAuthMode` parsing logic, and all predicate helper functions including `isHostedAuthMode` and `isEmailVerificationBypassed`.

- **[`src/server.ts`](https://github.com/every-app/open-seo/blob/main/src/server.ts)** — Reads `AUTH_MODE` at application startup and initializes the appropriate request routing pipeline for hosted or self-hosted operation.

- **[`src/middleware/ensure-user/resolve.ts`](https://github.com/every-app/open-seo/blob/main/src/middleware/ensure-user/resolve.ts)** — Contains the authentication enforcement logic that references the current mode to determine if a request requires a valid user session.

- **[`src/server/mcp/transport.ts`](https://github.com/every-app/open-seo/blob/main/src/server/mcp/transport.ts)** — Implements mode-aware request handling for internal MCP (Model Context Protocol) APIs, using the `whoami` verification tool.

- **[`docs/SELF_HOSTING_DOCKER.md`](https://github.com/every-app/open-seo/blob/main/docs/SELF_HOSTING_DOCKER.md)** — Deployment documentation providing practical guidance on setting `AUTH_MODE` in containerized environments.

## Summary

- OpenSEO provides three authentication strategies: `cloudflare_access` for Cloudflare Zero-Trust, `local_noauth` for development, and `hosted` for the SaaS platform.
- Configuration occurs exclusively through the `AUTH_MODE` environment variable, requiring no code modifications to switch modes.
- The `getAuthMode` function in [`src/lib/auth-mode.ts`](https://github.com/every-app/open-seo/blob/main/src/lib/auth-mode.ts) normalizes environment variable values into type-safe `AuthMode` types.
- Predicate helpers like `isHostedAuthMode` and `isEmailVerificationBypassed` enable clean conditional logic without string comparisons.
- Production deployments using `cloudflare_access` require additional Cloudflare Access Application configuration, while `local_noauth` is strictly for development use.

## Frequently Asked Questions

### What are the valid AUTH_MODE values in OpenSEO?

OpenSEO accepts three string values for `AUTH_MODE`: `cloudflare_access` for Cloudflare Zero-Trust integration, `local_noauth` for credential-free development, and `hosted` for the managed Every App platform. The `getAuthMode` function in [`src/lib/auth-mode.ts`](https://github.com/every-app/open-seo/blob/main/src/lib/auth-mode.ts) validates and normalizes these values at runtime, throwing an error if an unsupported mode is specified.

### How does Cloudflare Access authentication work technically?

When `AUTH_MODE` is set to `cloudflare_access`, OpenSEO expects Cloudflare's edge network to validate users before requests reach the application. Cloudflare injects a signed JWT in the `Authorization` header, which OpenSEO validates to extract identity claims and scopes. This moves authentication to the network edge, ensuring unauthenticated requests never reach your origin server.

### Is local_noauth safe for production environments?

No, `local_noauth` is explicitly designed for local development and testing only. When enabled, OpenSEO treats all requests as coming from an admin user without verifying credentials, creating significant security vulnerabilities if exposed to the internet. Production deployments should use either `cloudflare_access` or the `hosted` mode on the managed platform.

### How can I detect the current authentication mode in client-side code?

Use `getAuthMode(import.meta.env.AUTH_MODE)` to safely retrieve the mode in browser contexts, or use the `isHostedClientAuthMode()` predicate for build-time checks. These utilities ensure your client-side logic respects the same authentication configuration as the server, preventing mismatches between the build environment and runtime deployment.