# OmniRoute Authorization Pipeline and Route Classes: How Requests Are Validated

> Discover the OmniRoute authorization pipeline and its route classes. Learn how this centralized middleware system validates and secures every HTTP request before handlers execute.

- Repository: [Diego Rodrigues de Sa e Souza/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- Tags: architecture
- Published: 2026-07-05

---

**The OmniRoute authorization pipeline is a centralized middleware system in [`src/server/authz/pipeline.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/server/authz/pipeline.ts) that intercepts every HTTP request to classify it into one of three route classes—PUBLIC, CLIENT_API, or MANAGEMENT—and enforce security policies before handlers execute.**

The authorization pipeline in the diegosouzapw/OmniRoute repository ensures that every HTTP request undergoes a deterministic 14-step validation flow before reaching business logic. Located in [`src/server/authz/pipeline.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/server/authz/pipeline.ts), this system strips spoofed headers, validates body sizes, checks server drain state, and dispatches to class-specific policies. Understanding the pipeline architecture is essential for developers extending OmniRoute's security model or debugging authentication failures.

## The Three Route Classes

OmniRoute categorizes every endpoint into a specific **RouteClass** defined in [`src/server/authz/types.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/server/authz/types.ts) (lines 20-21):

```ts
export type RouteClass = "PUBLIC" | "CLIENT_API" | "MANAGEMENT";

```

The classification logic resides in [`src/server/authz/classify.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/server/authz/classify.ts), which maps URL patterns and HTTP methods to these classes using prefix-based rules such as `"public_prefix"` or `"dashboard_prefix"`. Each classification produces a `RouteClassification` object (defined in [`types.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/types.ts) lines 42-52) that includes the route class and a normalized path for policy evaluation.

- **PUBLIC** – Routes that are deliberately safe and require no authentication, such as health checks, login endpoints, and onboarding flows.
- **CLIENT_API** – Model-serving endpoints including `/api/v1/*`, `/api/v1beta/*`, and Codex alias routes that require valid API key authentication.
- **MANAGEMENT** – Dashboard, settings, provider-management, and administrative endpoints that use dashboard sessions or management-grade credentials.

## Pipeline Execution Flow

The `runAuthzPipeline` function executes 14 deterministic steps for every request. These steps run sequentially in [`src/server/authz/pipeline.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/server/authz/pipeline.ts) before any route handler receives the request:

1. **Generate request ID** – `generateRequestId()` (lines 24-25) creates a unique correlation token for distributed tracing.
2. **Classify the route** – `classifyRoute()` (lines 33-34) maps the request path and method to a `RouteClass`.
3. **Normalize pathname** – The classification returns a `normalizedPath` (line 34) used for policy checks.
4. **CORS handling** – Sets `corsRelaxOrigin` (lines 46-48) for client-API and read-only public endpoints.
5. **Drain check** – If `isDraining()` (lines 50-55) returns true, the pipeline returns a `503` response immediately.
6. **Body-size guard** – For non-GET/OPTIONS calls, `checkBodySize()` and `getBodySizeLimit()` (lines 57-68) validate against cached settings.
7. **Header sanitisation** – Strips `AUTHZ_TRUSTED_HEADERS` (lines 70-74) from forwarded requests to prevent header spoofing.
8. **Peer locality stamping** – `classifyStampedPeerLocality()` (lines 91-96) classifies the client IP as `local`, `loopback`, or `remote` and stores it in `AUTHZ_HEADER_PEER_LOCALITY`.
9. **OPTIONS pre-flight** – Short-circuit 204 response for CORS pre-flight requests (lines 98-104).
10. **Policy evaluation** – Selects a policy from the `POLICIES` map (lines 35-39) based on route class and executes `policy.evaluate()` (lines 31-33).
11. **Rejection handling** – Failed policies trigger `rejectionResponse()` (lines 50-67) returning JSON errors with request IDs.
12. **Management CSRF check** – For `MANAGEMENT` routes, `validateBrowserMutationOrigin()` and `validateDashboardCsrfToken()` (lines 44-58) enforce origin validation.
13. **Subject stamping** – On success, `stampSubject()` (lines 41-48) encodes the authenticated subject into response headers.
14. **Forward request** – Returns `NextResponse.next()` (lines 60-69) with sanitized headers to execute the route handler.

## Working with the Authorization Pipeline

Route handlers in OmniRoute interact with the pipeline through specific imports that enforce or consume authorization data.

### Enforcing Authorization in Route Handlers

Every API route imports `runAuthzPipeline` to enforce the authorization flow. The pipeline throws if the request is denied, otherwise it stamps authentication headers onto the request:

```ts
import { runAuthzPipeline } from "@/server/authz/pipeline";
import { NextRequest } from "next/server";

export async function GET(request: NextRequest) {
  // Enforce the pipeline (throws if the request is denied)
  const response = await runAuthzPipeline(request, { enforce: true });

  // If we reach here the request is authorised
  // request.headers now contains AUTHZ_HEADER_AUTH_ID, etc.
  const authId = request.headers.get("x-omniroute-auth-id");
  return new Response(`Authorized as ${authId}`);
}

```

This pattern is applied automatically to all `/api/*` routes because each handler imports `runAuthzPipeline` from the authorization layer.

### Accessing Authenticated Subject Data

After pipeline execution, handlers use `assertAuth` to retrieve the strongly typed `AuthSubject`:

```ts
import { assertAuth } from "@/server/authz/assertAuth";
import type { AuthSubject } from "@/server/authz/types";

export async function POST(request: NextRequest) {
  const { subject }: { subject: AuthSubject } = await assertAuth(request);
  // `subject.kind` will be "client_api_key", "dashboard_session", etc.
  console.log("Authenticated:", subject);
  // … proceed with the actual business logic …
}

```

The `assertAuth` function reads the `AUTHZ_HEADER_AUTH_*` values that `stampSubject` (lines 41-48) injected into the request headers during pipeline execution.

## Policy Architecture

Each route class maps to a specific policy implementation in the `POLICIES` dispatch table (lines 35-39 of [`pipeline.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/pipeline.ts)):

- **[`src/server/authz/policies/public.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/server/authz/policies/public.ts)** – Implements the `PUBLIC` policy with permissive allow-all logic for health checks and authentication endpoints.
- **[`src/server/authz/policies/clientApi.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/server/authz/policies/clientApi.ts)** – Validates API keys and enforces scope checks for `CLIENT_API` routes.
- **[`src/server/authz/policies/management.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/server/authz/policies/management.ts)** – Handles dashboard sessions, IP filtering, and CSRF protection for `MANAGEMENT` routes.

The pipeline uses header constants defined in [`src/server/authz/headers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/server/authz/headers.ts) for internal communication between steps, including `AUTHZ_TRUSTED_HEADERS` for sanitization and `AUTHZ_HEADER_PEER_LOCALITY` for IP classification.

## Summary

- The **authorization pipeline** in [`src/server/authz/pipeline.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/server/authz/pipeline.ts) executes 14 sequential validation steps before any route handler runs.
- **Route classes** (`PUBLIC`, `CLIENT_API`, `MANAGEMENT`) are defined in [`src/server/authz/types.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/server/authz/types.ts) and determined by [`src/server/authz/classify.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/server/authz/classify.ts).
- The pipeline automatically sanitizes headers, checks body sizes, validates CORS, and stamps peer locality for every request.
- **Policy evaluation** dispatches to class-specific implementations that return either an authenticated subject or a rejection response.
- Route handlers consume stamped authentication data via `assertAuth` or directly from `x-omniroute-auth-*` headers.

## Frequently Asked Questions

### What are the three route classes in OmniRoute?

The three route classes are **PUBLIC**, **CLIENT_API**, and **MANAGEMENT**, defined as a TypeScript union type in [`src/server/authz/types.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/server/authz/types.ts). PUBLIC routes require no authentication, CLIENT_API routes require valid API keys for model-serving endpoints, and MANAGEMENT routes require dashboard sessions or administrative credentials for configuration interfaces.

### How does the OmniRoute pipeline handle CORS requests?

The pipeline sets a `corsRelaxOrigin` flag (lines 46-48) for client-API and read-only public endpoints during classification. For OPTIONS pre-flight requests, the pipeline short-circuits with a 204 response (lines 98-104) before reaching policy evaluation, ensuring CORS compliance without unnecessary authentication checks.

### Where is the authorization pipeline implemented in OmniRoute?

The core implementation resides in [`src/server/authz/pipeline.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/server/authz/pipeline.ts), which exports the `runAuthzPipeline` function. Supporting files include [`src/server/authz/types.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/server/authz/types.ts) for type definitions, [`src/server/authz/classify.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/server/authz/classify.ts) for route classification logic, and `src/server/authz/policies/*.ts` for class-specific authorization rules.

### How do route handlers access authenticated subject data?

After `runAuthzPipeline` executes successfully, it stamps authentication data into request headers via `stampSubject` (lines 41-48). Route handlers then call `assertAuth(request)` from `src/server/authz/assertAuth` to retrieve a strongly typed `AuthSubject` object containing the user's identity, authentication kind (API key or session), and authorization scopes.