OpenSEO Chat Agents Authorization: How Access Control Works in the OpenSEO Source Code

Both OpenSEO chat agents require an authenticated user session linked to the correct organization, enforced via session cookies/JWT in hosted deployments or Cloudflare Access tokens in self-hosted mode.

The open-seo repository by every-app implements a multi-layered authorization system for its WebSocket-based chat agents. This article examines the exact authorization requirements, source code implementation, and configuration options that protect the SamChatAgent and OnboardingChatAgent from unauthorized access.

How OpenSEO Chat Agents Authorization Is Structured

The authorization flow centers on a single entry point in src/server.ts that branches based on agent type. All requests—whether WebSocket upgrades or standard HTTP fetches—must pass through this gate before reaching the underlying Durable Object.

The authorizeChatAgent Gate Function

Located at [lines 101-108 of src/server.ts](https://github.com/every-app/open-seo/blob/main/src/server.ts#L101-L108), authorizeChatAgent serves as the unified authorization dispatcher:

function authorizeChatAgent(request: Request, lobby: { className: string }) {
  switch (lobby.className) {
    case "SAM_CHAT":
      return authorizeSamChat(request);
    case "ONBOARDING_CHAT":
      return authorizeOnboardingChat(request);
    default:
      return new Response("Forbidden", { status: 403 });
  }
}

This function extracts the className from the lobby configuration and delegates to the appropriate specialized authorizer. Any unrecognized agent type immediately returns 403 Forbidden.

What Credentials OpenSEO Chat Agents Validate

Both authorizeSamChat and authorizeOnboardingChat perform identical authorization checks according to the source code in src/server.ts. These checks ensure only legitimate users access organizational chat data.

Required Authentication Components

  • Valid session identification – The authorizer extracts a session cookie or JWT token from the request headers
  • Organization ownership verification – The resolved sessionId must map to a user belonging to the organization that owns the target Durable Object
  • Self-hosted mode compliance – Additional environment-specific checks based on AUTH_MODE configuration

Authorization Failure Handling

When any check fails, the authorizer returns a 403 Forbidden response before the request reaches the chat agent Durable Object. This prevents unauthorized WebSocket connections and HTTP API calls at the edge.

Self-Hosted Deployment Authorization Modes

OpenSEO supports three authentication configurations controlled by the AUTH_MODE environment variable. These modes determine how strictly the chat agent authorization layer enforces access control.

Mode Authorization Behavior Use Case
Default (hosted) Standard session cookie/JWT validation against user database every-app cloud platform
cloudflare_access Validates Cloudflare Access token in addition to session checks Self-hosted with Cloudflare Access
local_noauth Bypasses authentication entirely for local development Local development only

The authorizeSamChat and authorizeOnboardingChat functions reference AUTH_MODE to apply these variations, as implemented in src/server.ts.

Routing After OpenSEO Chat Agents Authorization

Successful authorization permits the request to proceed through routeChatAgents, which handles both WebSocket upgrades and HTTP fetch requests. This routing logic appears at [lines 55-60 of src/server.ts](https://github.com/every-app/open-seo/blob/main/src/server.ts#L55-L60):

await routeAgentRequest(request, env, {
  onBeforeConnect: (req, lobby) => authorizeChatAgent(req, lobby),
  onBeforeRequest: (req, lobby) => authorizeChatAgent(req, lobby),
});

Two distinct hooks ensure authorization runs:

  • onBeforeConnect – Executes before WebSocket upgrade for real-time chat connections
  • onBeforeRequest – Executes before standard HTTP requests to the chat agent API

Both hooks invoke the same authorizeChatAgent function, maintaining consistent security across transport protocols.

Key Source Files for OpenSEO Chat Agents Authorization

File Path Purpose
[src/server.ts](https://github.com/every-app/open-seo/blob/main/src/server.ts) Core routing, authorizeChatAgent, and routeChatAgents implementation
[src/server/features/sam/SamChatAgent.ts](https://github.com/every-app/open-seo/blob/main/src/server/features/sam/SamChatAgent.ts) SAM chat Durable Object
[src/server/features/onboarding/OnboardingChatAgent.ts](https://github.com/every-app/open-seo/blob/main/src/server/features/onboarding/OnboardingChatAgent.ts) Onboarding chat Durable Object
src/middleware/ensure-user/ Session extraction and user validation utilities

Summary

  • OpenSEO chat agents require authenticated sessions – No public access; all requests must present valid credentials
  • Authorization splits by agent typeauthorizeChatAgent dispatches to authorizeSamChat or authorizeOnboardingChat based on lobby.className
  • Organization scoping is mandatory – Sessions must belong to the organization owning the target Durable Object
  • Self-hosted flexibilityAUTH_MODE supports Cloudflare Access integration or local development bypass
  • Dual-path protection – Both WebSocket connections and HTTP requests pass through identical authorization checks

Frequently Asked Questions

What happens if I try to connect to an OpenSEO chat agent without authentication?

The connection is rejected with a 403 Forbidden response before reaching the Durable Object. The authorizeChatAgent function returns this status when no valid session is found or when the session's organization doesn't match the target agent's organization.

Can I disable authentication for OpenSEO chat agents in development?

Yes, by setting AUTH_MODE=local_noauth in your environment configuration. According to the source code in src/server.ts, this mode bypasses the standard session validation. This configuration is intended only for local development and should never be used in production deployments.

Does OpenSEO chat agents authorization work differently for WebSocket versus HTTP requests?

No, both transport types use identical authorization logic. The routeAgentRequest function in src/server.ts applies authorizeChatAgent through both onBeforeConnect (WebSocket) and onBeforeRequest (HTTP) hooks, ensuring consistent security regardless of how clients interact with the chat agents.

What identifies which authorization path a request takes?

The className property of the lobby object determines the path. SAM_CHAT routes to authorizeSamChat; ONBOARDING_CHAT routes to authorizeOnboardingChat. Any other value triggers an immediate 403 response from the authorizeChatAgent dispatcher.

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 →