How OpenSEO Validates Self-Host Configurations: Team Domains, API Keys, and Telemetry

OpenSEO validates self-host configurations using a dedicated pre-flight system that checks environment variables—such as team domains, API keys, and authentication settings—before the application starts, aborting startup immediately if critical values are malformed or missing.

When deploying OpenSEO (from the every-app/open-seo repository) in a self-hosted environment, the application relies on a strict validation layer to prevent runtime failures caused by misconfigured environment variables. This system combines a pure validation library with an orchestration script that produces a uniform report consumable by both the container startup process and the /api/health endpoint.

Core Validation Architecture

The validation system splits responsibilities between two primary components in the codebase.

src/shared/selfhost-checks.ts contains stateless, pure functions that validate individual configuration values. These functions perform format checks and pattern matching without side effects.

src/lib/selfhost-preflight.ts orchestrates the full validation suite. It imports the pure checkers, executes them against the runtime environment, and aggregates results into a PreflightResult object. If any check returns a fail level, the container aborts startup with a concise error message rather than attempting to boot with invalid configuration.

Validating Critical Configuration Values

The pure validation library handles the most common configuration mistakes by enforcing strict format requirements on essential variables.

Team Domain Format

The validateTeamDomain function ensures that TEAM_DOMAIN is a complete HTTPS URL required for Cloudflare Access authentication. According to the source code in src/shared/selfhost-checks.ts (lines 11-32), the validator checks that the string starts with https:// and contains a valid hostname structure.

import { validateTeamDomain } from "@/shared/selfhost-checks";

const result = validateTeamDomain(process.env.TEAM_DOMAIN ?? "");
if (!result.ok) {
  console.error("Invalid TEAM_DOMAIN:", result.message);
  // startup will abort with a [FAIL] badge
}

If this check fails, the pre-flight script exits immediately, preventing the middleware in src/middleware/ensure-user/cloudflareAccess.ts from attempting to authenticate against an invalid domain.

DataForSEO API Key Structure

The looksLikeDataForSeoKey function (lines 34-43 of src/shared/selfhost-checks.ts) validates that DATAFORSEO_API_KEY is a base-64-encoded string representing a login:password pair. This catches common encoding errors before the application attempts to communicate with the DataForSEO service.

import { looksLikeDataForSeoKey } from "@/shared/selfhost-checks";

if (!looksLikeDataForSeoKey(process.env.DATAFORSEO_API_KEY ?? "")) {
  console.warn(
    "DATAFORSEO_API_KEY does not decode to a login:password pair – double‑check the base64 encoding."
  );
}

Telemetry Opt-Out Detection

The isTelemetryOptOutValue function (lines 45-53 of src/shared/selfhost-checks.ts) interprets the OPENSEO_TELEMETRY_DISABLED environment variable. Any value other than "0", "false", "no", or "off" is treated as an opt-out, giving administrators explicit control over data collection.

import { isTelemetryOptOutValue } from "@/shared/selfhost-checks";

const telemetryDisabled = isTelemetryOptOutValue(process.env.OPENSEO_TELEMETRY_DISABLED);
if (telemetryDisabled) {
  console.info("Telemetry is disabled per OPENSEO_TELEMETRY_DISABLED");
}

Authentication and Optional Feature Checks

Beyond basic format validation, the pre-flight script performs complex cross-variable validation for authentication and optional integrations.

Auth Mode Validation

The checkAuthMode function in src/lib/selfhost-preflight.ts (lines 35-101) validates that the selected AUTH_MODE has all required dependencies. It checks for the presence of BETTER_AUTH_URL, BETTER_AUTH_SECRET, GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, and POLICY_AUD according to the specific authentication mode configured. Missing required variables for the selected mode trigger a fail level result.

Optional Integrations

The checkOptionalFeatures function (lines 56-104 of src/lib/selfhost-preflight.ts) performs non-blocking validation of Google Search Console credentials and OpenRouter AI keys. When these values are partially configured, the function emits warnings rather than failures, allowing the application to start with reduced functionality while alerting administrators to incomplete setups.

Running the Self-Host Pre-Flight Check

The runSelfhostPreflight function serves as the entry point for the validation workflow. As implemented in src/lib/selfhost-preflight.ts, it accepts an EnvRecord, executes all checks via runSelfhostChecks(env), and returns a PreflightResult containing an array of PreflightItems and a boolean failed flag.

// src/lib/selfhost-preflight.ts
export function runSelfhostPreflight(env: EnvRecord): PreflightResult {
  const items = runSelfhostChecks(env);
  // … add runtime checks for ALLOWED_HOST, scheduled jobs, etc.
  return { items, failed: items.some(i => i.level === "fail") };
}

During container startup, the script at scripts/selfhost-preflight.ts invokes this function and formats the output for console visibility:

import { runSelfhostPreflight, formatPreflightReport } from "@/lib/selfhost-preflight";

const result = runSelfhostPreflight(process.env);
console.log(formatPreflightReport(result));
if (result.failed) process.exit(1);

The same validation results are exposed via the /api/health endpoint through src/server/lib/setup-status.ts, providing runtime visibility into configuration health without requiring container restart.

Summary

  • Pure validation functions in src/shared/selfhost-checks.ts handle format-specific checks for team domains, API keys, and telemetry settings.
  • Orchestration logic in src/lib/selfhost-preflight.ts runs comprehensive checks via runSelfhostPreflight, validating authentication modes and optional features.
  • Early failure prevents the application from starting with invalid configuration, avoiding cryptic runtime errors minutes into deployment.
  • Health endpoint exposure at /api/health surfaces the same PreflightResult objects for operational monitoring.

Frequently Asked Questions

What happens if the TEAM_DOMAIN environment variable is malformed?

OpenSEO aborts container startup immediately. The validateTeamDomain function returns a failure result when the value is not a complete HTTPS URL, and the pre-flight script exits with code 1 before the application begins serving traffic.

How does OpenSEO verify the DataForSEO API key format?

The looksLikeDataForSeoKey function attempts to base64-decode the string and verifies it contains a colon-separated login:password pair. This catches encoding errors early but does not verify credentials against the live API.

Can OpenSEO start if optional features like Google Search Console are partially configured?

Yes, but with warnings. The checkOptionalFeatures validator emits warning-level PreflightItems for partially configured optional integrations, allowing startup while alerting administrators via console logs and the /api/health endpoint.

Where can I view the validation results after the container starts?

The src/server/lib/setup-status.ts module exposes the pre-flight results at the /api/health endpoint, returning the same PreflightResult JSON that was generated during container initialization.

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 →