How the OmniRoute Authorization Pipeline Classifies Routes: A Deep Dive into Route Security Zones
OmniRoute's authorization pipeline classifies every incoming request into one of three security zones—PUBLIC, CLIENT_API, or MANAGEMENT—using the classifyRoute function in src/server/authz/classify.ts, which applies a three-stage evaluation process to determine which access policy governs the request.
The classification system serves as the foundation of OmniRoute's security model, determining whether a route requires authentication, CSRF protection, or specific scopes. By analyzing the request path and HTTP method before any authorization checks occur, the pipeline ensures that public endpoints remain accessible while protecting sensitive management and client API resources.
Core Classification Logic in classify.ts
The entry point for all route classification is src/server/authz/classify.ts, which exports the primary classification function used by the authorization middleware.
The classifyRoute Function Signature
The classification process begins with a single exported function that inspects the incoming request:
export function classifyRoute(rawPath: string, method: string = "GET"): RouteClassification
This function accepts the raw request path and HTTP method, then returns a RouteClassification object that the pipeline uses to select the appropriate security policy.
The RouteClassification Object
The function returns an object containing three critical properties:
routeClass– A string literal of either"PUBLIC","CLIENT_API", or"MANAGEMENT"indicating the security zone.reason– A descriptive string explaining the classification rationale (e.g.,root_redirect,public_prefix,client_api_alias).normalizedPath– The canonical pathname after alias resolution and trailing-slash cleanup.
These types are defined in src/server/authz/types.ts, which provides the TypeScript interfaces for the entire authorization system.
The Three-Stage Classification Process
The classifyRoute function operates through three sequential stages, with each stage potentially determining the final classification.
Stage 1: Path Normalization and Alias Handling
First, the normalizePathname helper ensures path consistency. It guarantees the path starts with /, removes trailing slashes, and rewrites known aliases. For example:
/v1→/api/v1/chat/completions→/api/v1/chat/completions
When an alias is applied, the reason field records either client_api_alias or client_api_double_prefix, ensuring traceability for debugging.
Stage 2: Static Route Checks
After normalization, the function checks against hard-coded route patterns in priority order:
/→ MANAGEMENT with reasonroot_redirect/dashboard/onboarding→ PUBLIC with reasonsetup_wizard/connect…→ PUBLIC with reasonpublic_connect_page- Any path beginning with
/dashboard→ MANAGEMENT with reasondashboard_prefix
These static checks handle core application pages before evaluating API routes.
Stage 3: API-Prefix and Whitelist Evaluation
For paths starting with /api/, the classification applies specific prefix rules:
-
Client API Detection – Paths starting with
/api/v1or/api/v1betaare automatically classified as CLIENT_API with reasons likeclient_api_v1. -
Public API Evaluation – For other
/api/…paths, the helperisPublicApiRoute(imported fromsrc/shared/constants/publicApiRoutes.ts) evaluates two whitelists:PUBLIC_READONLY_API_ROUTE_PREFIXEScombined withPUBLIC_READONLY_METHODS– for read-only public endpointsPUBLIC_READWRITE_API_ROUTE_PREFIXES– for writable public endpoints
-
Management Fallback – If no public rules match, the route defaults to MANAGEMENT with reason
management_api.
If no rule matches across all stages, the function defaults to MANAGEMENT with reason fallback_management.
Integration with the Authorization Pipeline
The classification result flows directly into src/server/authz/pipeline.ts, which orchestrates the complete request authorization flow. Based on the routeClass property, the pipeline selects the appropriate RoutePolicy:
publicPolicy– Minimal security, no authentication requiredclientApiPolicy– API-key authentication with optional scope validationmanagementPolicy– Full session authentication, CSRF protection, and admin scope requirements
This architecture ensures that classification decisions made in classify.ts directly determine which authentication mechanisms and security headers apply to the request.
Practical Classification Examples
The following TypeScript examples demonstrate how various paths are classified according to the OmniRoute source code:
import { classifyRoute } from "@/server/authz/classify";
const examples = [
{ path: "/", method: "GET" },
{ path: "/dashboard/settings", method: "GET" },
{ path: "/v1/chat/completions", method: "POST" },
{ path: "/connect/abc123", method: "GET" },
{ path: "/api/v1/models", method: "GET" },
{ path: "/api/internal/secret", method: "POST" },
];
examples.forEach(({ path, method }) => {
const result = classifyRoute(path, method);
console.log(
`${method} ${path} → ${result.routeClass} (reason: ${result.reason})`,
);
});
/* Sample output:
GET / → MANAGEMENT (reason: root_redirect)
GET /dashboard/settings → MANAGEMENT (reason: dashboard_prefix)
POST /v1/chat/completions → CLIENT_API (reason: client_api_alias)
GET /connect/abc123 → PUBLIC (reason: public_connect_page)
GET /api/v1/models → CLIENT_API (reason: client_api_v1)
POST /api/internal/secret → MANAGEMENT (reason: management_api)
*/
Summary
- Route classification occurs in
src/server/authz/classify.tsvia theclassifyRoutefunction, which categorizes every request as PUBLIC, CLIENT_API, or MANAGEMENT. - Three-stage processing includes path normalization/alias handling, static route checks for dashboard pages, and API-prefix evaluation against whitelists.
- Default security falls back to MANAGEMENT whenever no explicit rules match, ensuring secure-by-default behavior.
- Pipeline integration means classification results directly determine which authorization policy (
publicPolicy,clientApiPolicy, ormanagementPolicy) enforces the request insrc/server/authz/pipeline.ts. - Public API routes are defined in
src/shared/constants/publicApiRoutes.tsusing prefix and method whitelists rather than explicit route registration.
Frequently Asked Questions
What are the three route classes in OmniRoute?
OmniRoute recognizes PUBLIC (unauthenticated endpoints like connect pages), CLIENT_API (versioned API endpoints under /api/v1 or /api/v1beta), and MANAGEMENT (dashboard and internal administrative interfaces). Each class triggers different authentication requirements and security headers when processed by the authorization pipeline.
How does OmniRoute handle API route aliases?
The normalizePathname function in src/server/authz/classify.ts automatically rewrites legacy or convenience paths to their canonical equivalents. For instance, /v1/chat/completions becomes /api/v1/chat/completions before classification occurs, with the reason field set to client_api_alias to indicate the transformation.
What happens if a route doesn't match any classification rules?
When no static rules, API prefixes, or whitelist entries match the request path, the classifyRoute function returns MANAGEMENT with the reason fallback_management. This secure-by-default approach ensures that unclassified endpoints receive the highest level of protection rather than unintentional public exposure.
Where are public API routes defined in OmniRoute?
Public API routes are declared in src/shared/constants/publicApiRoutes.ts, which exports the isPublicApiRoute helper function. This file maintains two whitelists—PUBLIC_READONLY_API_ROUTE_PREFIXES for read-only operations and PUBLIC_READWRITE_API_ROUTE_PREFIXES for writable endpoints—that determine whether an /api/ route should be classified as PUBLIC or MANAGEMENT.
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 →