OmniRoute Authentication and Authorization Pipeline: Route Classes Explained
OmniRoute uses a centralized middleware pipeline in src/server/authz/pipeline.ts that classifies every request into one of three route classes—PUBLIC, CLIENT_API, or MANAGEMENT—and delegates authentication to specialized policies that return a simple allow/reject decision before stamping the validated subject into response headers.
The OmniRoute routing platform implements a strict authentication and authorization pipeline that intercepts every incoming request to enforce security boundaries. By categorizing endpoints into three distinct route classes, the system applies granular access controls while maintaining consistent CORS, IP filtering, and tracing logic across health checks, SDK-facing APIs, and dashboard operations.
The Three Route Classes
The classifyRoute function in src/server/authz/classify.ts examines the URL pathname and HTTP method to assign a route class that determines acceptable authentication methods:
- PUBLIC – Read-only endpoints such as health checks and provider catalogs. These may allow anonymous access or optional Bearer tokens depending on the
REQUIRE_API_KEYconfiguration. - CLIENT_API – Standard REST endpoints under
/v1/*consumed by SDKs, CLI tools, and browser clients. Requires API keys, Bearer tokens, or valid dashboard sessions. - MANAGEMENT – Dashboard UI, MCP tools, and internal operations requiring dashboard-session cookies, management-scope API keys, CLI tokens, or special bridge secrets.
Pipeline Execution Flow
The runAuthzPipeline function in src/server/authz/pipeline.ts processes every request through fourteen discrete stages before reaching the downstream handler. This centralized approach ensures that cross-cutting security concerns execute in a predictable order.
Phase 1: Request Initialization and Classification
The pipeline first generates a UUID via generateRequestId and assigns it to the response for distributed tracing. It then calls classifyRoute to determine the route class and normalized path, storing these in the AUTHZ_HEADER_ROUTE_CLASS and AUTHZ_HEADER_REQUEST_ID headers. For non-loopback requests, the classifyStampedPeerLocality helper stamps whether the peer is loopback, remote, or another classification.
Phase 2: Pre-Flight Security Checks
Before authentication occurs, the pipeline performs several safety validations:
- CORS handling – For
CLIENT_APIand read-onlyPUBLICroutes,corsRelaxOriginrelaxes theOriginheader to allow browser and Electron clients without credentials. - Graceful shutdown guard – If the server is draining (
isDraining), the pipeline returns an immediate 503 response. - Body size validation – For non-GET/OPTIONS requests,
checkBodySizevalidates the payload against cached settings. - Header sanitization – The pipeline strips trusted headers like peer-IP stamps from forwarded requests to prevent spoofing, as implemented in the header stripping loop at lines 102‑110.
Phase 3: Policy Evaluation
When options.enforce is true, the pipeline selects a policy from the POLICIES map based on the route class and evaluates it against a PolicyContext:
publicPolicyfor PUBLIC routesclientApiPolicyfor CLIENT_API routesmanagementPolicyfor MANAGEMENT routes
Each policy returns an AuthOutcome object containing either an allow status with the authenticated subject or a reject status with an error code.
Phase 4: Post-Authentication Controls
For denied requests, the rejectionResponse helper returns a JSON payload with code, message, and correlation_id. Dashboard rejections trigger a redirect to the login page.
For allowed MANAGEMENT requests, additional protections apply:
- CSRF validation – State-changing methods (
POST,PUT,DELETE) validate theOriginheader and fall back to a dashboard CSRF token via the CSRF block at lines 76‑89. - Subject stamping – The
stampSubjectfunction writes the authentication kind (dashboard_session,client_api_key,management_key, etc.) into response headers includingAUTHZ_HEADER_AUTH_KINDandAUTHZ_HEADER_AUTH_ID.
Finally, the pipeline returns NextResponse.next() with enriched headers, applying CORS policies and optionally refreshing the dashboard JWT cookie.
Route Class Policy Implementation
PUBLIC Policy
The publicPolicy in src/server/authz/policies/public.ts defaults to permissive for read-only endpoints, allowing anonymous access. For non-read-only operations classified as PUBLIC, it delegates to the same Bearer/API-key validation logic used by clientApiPolicy unless explicitly marked as public-readonly.
CLIENT_API Policy
Located in src/server/authz/policies/clientApi.ts, the clientApiPolicy accepts credentials from multiple sources:
Authorization: Bearer <token>x-api-keyorx-goog-api-keyheaders- Legacy CLI token headers
If no token is present, the policy allows:
- WebSocket handshake requests (
/api/v1/ws) - Valid dashboard sessions
- Anonymous access when
REQUIRE_API_KEYis disabled
When a token exists, validateApiKey checks it against the API-key table. Success grants access as client_api_key; failure rejects with 401 AUTH_002 unless REQUIRE_API_KEY is off, in which case it degrades to anonymous.
MANAGEMENT Policy
The managementPolicy in src/server/authz/policies/management.ts implements a tiered authentication hierarchy for privileged operations:
- WS-bridge secret – Validates the
OMNIROUTE_WS_BRIDGE_SECRETfor internal process communication. - LOCAL_ONLY bypass – Certain paths allow non-loopback access only with a manage-scope API key or authenticated dashboard session.
- Internal tokens – Supports inspector ingest tokens and internal model-sync requests.
- CLI token – Loopback-only authentication via
CLI_TOKEN_HEADER. - Optional auth-disabled paths – Allows anonymous when
isAuthRequiredis false. - Dashboard session – Cookie-based session validation.
- Access tokens – Validates
oma_prefixed tokens viaevaluateAccessTokenAuth. - Management API keys – Requires
manage,admin, ormcp:connectscope for/api/mcp/*paths.
Invalid Bearer tokens result in 403; missing credentials result in 401.
Security Mechanisms and Middleware Integration
IP Filtering and Peer Validation
After classification, checkRequestIP evaluates the external IP against operator-defined blacklists and whitelists for all non-loopback requests, as seen at lines 146‑160 of the pipeline.
Middleware Configuration
To enforce the pipeline across all API routes, implement the following middleware in your Next.js application:
// src/middleware/authz.ts
import { runAuthzPipeline } from '@/server/authz/pipeline';
import type { NextRequest } from 'next/server';
export async function middleware(request: NextRequest) {
// Enforce the full authz pipeline for every request.
// The `enforce: true` flag triggers policy evaluation.
return await runAuthzPipeline(request, { enforce: true });
}
Apply this middleware to the /api/** route matcher to ensure consistent security headers and authentication checks across the entire API surface.
Summary
- OmniRoute uses three route classes (PUBLIC, CLIENT_API, MANAGEMENT) to apply distinct authentication requirements based on endpoint sensitivity.
- The authorization pipeline in
src/server/authz/pipeline.tscentralizes CORS, body-size limits, IP filtering, and header sanitization before delegating to policy-specific logic. - Policy modules are composable functions returning
AuthOutcomeobjects, making the system testable and extensible. - Authentication results are stamped into response headers (
AUTHZ_HEADER_AUTH_KIND,AUTHZ_HEADER_AUTH_ID) for downstream audit logging and service consumption. - CSRF protection and session refresh are automatically applied to MANAGEMENT route mutations, while PUBLIC routes remain open for health checks and metadata access.
Frequently Asked Questions
What is the difference between CLIENT_API and MANAGEMENT route classes?
CLIENT_API routes are designed for external SDK and CLI consumption, accepting scoped API keys and Bearer tokens for specific resources. MANAGEMENT routes control dashboard access and internal operations, requiring broader permissions such as manage or admin scope, dashboard sessions, or internal bridge secrets. The MANAGEMENT policy also enforces additional CSRF protection for state-changing operations that CLIENT_API does not require.
How does OmniRoute handle anonymous access to PUBLIC endpoints?
The publicPolicy allows anonymous access specifically for read-only operations like health checks and catalog listings. If a PUBLIC endpoint performs non-read operations, the policy falls back to the same API-key validation used by CLIENT_API unless explicitly configured otherwise via REQUIRE_API_KEY settings.
What authentication methods are supported for MANAGEMENT routes?
MANAGEMENT routes support ten distinct authentication methods evaluated in strict order: WS-bridge secrets, LOCAL_ONLY bypass with management keys, inspector ingest tokens, internal model-sync requests, loopback CLI tokens, auth-disabled path exceptions, dashboard sessions, oma_ access tokens, management-scope API keys, and OAuth Bearer tokens. This hierarchy allows both automated internal services and human operators to access dashboard functionality through appropriate credentials.
Where is the authentication outcome recorded for downstream services?
After successful policy evaluation, the stampSubject function writes the authentication results into response headers including AUTHZ_HEADER_AUTH_KIND (e.g., dashboard_session, client_api_key), AUTHZ_HEADER_AUTH_ID (the masked identifier), and AUTHZ_HEADER_REQUEST_ID for correlation. These headers allow upstream proxies and logging services to identify the caller without re-validating the token.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →