TEAM_DOMAIN Requirements for Self-Hosted OpenSEO: Configuration and Validation Guide

The TEAM_DOMAIN environment variable must be a full HTTPS URL (e.g., https://your-team.cloudflareaccess.com) and is required whenever AUTH_MODE is set to cloudflare_access in self-hosted OpenSEO deployments.

In the every-app/open-seo repository, TEAM_DOMAIN serves as the authoritative endpoint for validating Cloudflare Access JWT tokens. This variable undergoes strict validation during application startup and runtime to ensure secure authentication flows.

Where TEAM_DOMAIN Is Validated in OpenSEO

The codebase enforces TEAM_DOMAIN requirements through two primary validation layers that operate during preflight checks and runtime authentication.

Core Validation Logic in selfhost-checks.ts

In src/shared/selfhost-checks.ts, the validateTeamDomain function implements the format requirements. This utility ensures that any provided value is a properly formatted HTTPS URL before the application accepts it. The function strips trailing slashes to normalize the origin and explicitly rejects plain hostnames or HTTP schemes. According to the source, malformed URLs trigger the error: “TEAM_DOMAIN must be a full https URL like https://your-team.cloudflareaccess.com”.

Preflight Configuration Checks

The src/lib/selfhost-preflight.ts file contains the startup validation logic that checks for the presence of TEAM_DOMAIN when AUTH_MODE is configured for Cloudflare Access. The configuration check at lines 72–89 verifies that the variable is not only set but also paired with POLICY_AUD. If TEAM_DOMAIN is missing or empty when Cloudflare Access mode is active, the preflight script returns: “TEAM_DOMAIN must be set if using Cloudflare Access mode.”

TEAM_DOMAIN Format Requirements

Based on the validation logic implemented in the OpenSEO source code, your environment configuration must satisfy these specific criteria:

  • HTTPS Protocol Required: The value must start with https://. Plain hostnames (e.g., team.cloudflareaccess.com) or HTTP URLs are explicitly rejected.
  • Full Origin URL: Must include the complete origin including the protocol and host (e.g., https://team.cloudflareaccess.com). Path components are not permitted.
  • Trailing Slash Normalization: While the validator strips trailing slashes internally, you should provide the clean origin without paths to avoid processing errors.
  • Mandatory Pairing: When AUTH_MODE=cloudflare_access, TEAM_DOMAIN must be configured alongside POLICY_AUD for successful token validation.
  • Type Definition: In src/env.d.ts at line 29, the variable is typed as an optional string (TEAM_DOMAIN?: string), though runtime checks enforce its presence when required.

Configuration Example

Configure your environment variables following this pattern to satisfy OpenSEO's validation requirements:

// ✅ Correct configuration
TEAM_DOMAIN=https://myteam.cloudflareaccess.com
POLICY_AUD=your-policy-audience-id
AUTH_MODE=cloudflare_access

// ❌ Incorrect - missing protocol
TEAM_DOMAIN=myteam.cloudflareaccess.com

// ❌ Incorrect - using HTTP instead of HTTPS
TEAM_DOMAIN=http://myteam.cloudflareaccess.com

// ❌ Incorrect - empty string triggers preflight error
TEAM_DOMAIN=

The src/middleware/ensure-user/cloudflareAccess.ts file imports getValidatedTeamDomain from the self-host checks module and uses the validated HTTPS origin to fetch the team's JWKS for JWT verification. If validation fails, the middleware prevents user authentication from proceeding.

Summary

  • TEAM_DOMAIN must be a complete HTTPS URL including the https:// scheme when running self-hosted OpenSEO with Cloudflare Access authentication.
  • The validateTeamDomain function in src/shared/selfhost-checks.ts enforces the HTTPS requirement and normalizes the URL format.
  • The preflight checker in src/lib/selfhost-preflight.ts ensures the variable is present and paired with POLICY_AUD when AUTH_MODE=cloudflare_access.
  • Invalid configurations trigger specific error messages during startup or runtime, preventing the application from accepting authentication tokens.

Frequently Asked Questions

What happens if TEAM_DOMAIN is not set in Cloudflare Access mode?

The preflight configuration check in src/lib/selfhost-preflight.ts will fail with the error “TEAM_DOMAIN must be set if using Cloudflare Access mode”, and the application will not start. This validation occurs during the initialization sequence before the server accepts any requests.

Can I use an HTTP URL for TEAM_DOMAIN?

No. The validateTeamDomain function in src/shared/selfhost-checks.ts explicitly requires the https:// protocol. HTTP URLs, plain hostnames, or malformed strings are rejected with a validation error specifying that a full HTTPS URL is required.

Do I need to include POLICY_AUD with TEAM_DOMAIN?

Yes. When AUTH_MODE is set to cloudflare_access, the validation logic in src/lib/selfhost-preflight.ts checks for the presence of both TEAM_DOMAIN and POLICY_AUD. Both variables are required to validate incoming Cloudflare Access tokens against the correct policy audience.

Where is the TEAM_DOMAIN environment variable defined in the codebase?

The TypeScript type definition for TEAM_DOMAIN is located in src/env.d.ts at line 29, where it is declared as an optional string. However, the runtime requirements and validation logic are implemented in src/shared/selfhost-checks.ts and enforced during preflight checks in src/lib/selfhost-preflight.ts.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →