How to Implement Optional Authentication in OmniRoute: A Complete Guide
Optional authentication in OmniRoute is controlled by the requireLogin runtime flag stored in src/lib/db/settings.ts; when set to false, management-tier routes accept unauthenticated requests while always-protected routes remain secured.
Optional authentication in the diegosouzapw/OmniRoute repository is governed by a runtime boolean that toggles credential enforcement on standard API routes. When disabled, the authorization pipeline permits anonymous access to most endpoints while maintaining mandatory authentication for destructive operations. This architecture allows administrators to deploy open-access instances without sacrificing security for critical system functions.
Understanding the Three-Tier Authorization Model
OmniRoute classifies every incoming request into one of three distinct authorization tiers defined in src/server/authz/routeGuard.ts:
LOCAL-ONLY: Routes that spawn child processes or execute system commands. These endpoints automatically reject connections from non-loopback network interfaces, regardless of authentication status or the requireLogin setting.
ALWAYS-PROTECTED: Destructive endpoints that mandate valid authentication even when the global requireLogin flag is disabled. This tier is enforced by the isAlwaysProtectedPath function (lines 78-80) against the ALWAYS_PROTECTED_API_PATHS constant.
MANAGEMENT: Standard API routes that respect the runtime requireLogin boolean. When this flag is false, these routes operate in optional authentication mode, accepting both authenticated and anonymous requests while still validating tokens when present.
The runAuthzPipeline function orchestrates these checks for every request entering the Next.js route handlers.
Configuring the requireLogin Runtime Flag
The core mechanism resides in the settings database. The requireLogin boolean defaults to true but can be toggled to enable optional authentication:
// src/lib/db/settings.ts (lines 61-65)
// https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/src/lib/db/settings.ts#L61-L65
requireLogin: true,
Changes to this value are applied live through src/lib/config/runtimeSettings.ts, which updates the in-memory authorization pipeline without requiring a server restart. When requireLogin is false, the runAuthzPipeline skips credential validation for management-tier routes while still enforcing protection for local-only and always-protected paths.
Creating Routes with Optional Authentication
To implement an endpoint that respects the optional authentication setting, create your route handler in src/app/api/v1/ and avoid adding it to the protected lists. The pipeline automatically evaluates the requireLogin flag before your handler executes.
Example: Anonymous-Compatible GET Endpoint
// src/app/api/v1/status/route.ts
import { getSettings } from "@/lib/db/settings";
export async function GET(request: Request) {
const { requireLogin } = await getSettings();
if (requireLogin) {
// The authz pipeline has already verified the request
const userId = request.headers.get("x-omniroute-user-id");
return Response.json({ status: "ok", user: userId });
}
// Optional auth mode: treat as anonymous
return Response.json({ status: "ok", user: "anonymous" });
}
Example: Conditional POST Handler
// src/app/api/v1/feedback/route.ts
import { getSettings } from "@/lib/db/settings";
export async function POST(request: Request) {
const { requireLogin } = await getSettings();
const body = await request.json();
const author = requireLogin
? request.headers.get("x-omniroute-user-id") ?? "unknown"
: "anonymous";
// Process feedback...
return new Response(`Recorded from ${author}`, { status: 201 });
}
Protecting Critical Routes
Destructive operations remain protected regardless of the requireLogin setting. These endpoints are listed in the ALWAYS_PROTECTED_API_PATHS array in src/server/authz/routeGuard.ts:
// src/server/authz/routeGuard.ts (lines 20-28)
// https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/src/server/authz/routeGuard.ts#L20-L28
export const ALWAYS_PROTECTED_API_PATHS: ReadonlyArray<string> = [
"/api/shutdown",
"/api/providers/health-autopilot/actions",
"/api/settings/database",
"/api/db-backups",
];
The isAlwaysProtectedPath function (lines 78-80) evaluates incoming requests against this list:
// src/server/authz/routeGuard.ts (lines 78-80)
// https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/src/server/authz/routeGuard.ts#L78-L80
export function isAlwaysProtectedPath(path: string) {
return ALWAYS_PROTECTED_API_PATHS.some(p => path === p || path.startsWith(p));
}
To permanently protect a new route, add its exact path or prefix to the ALWAYS_PROTECTED_API_PATHS array.
Manage-Scope Bypass for Local-Only Routes
Local-only routes (such as those spawning processes) typically reject remote connections. However, OmniRoute supports a manage-scope bypass allowing remote access when clients present valid management API keys.
This behavior is controlled by settings in src/lib/db/settings.ts (lines 22-30):
localOnlyManageScopeBypassEnabled: Boolean toggle (defaulttrue)localOnlyManageScopeBypassPrefixes: Array of path prefixes (default["/api/mcp/"])
The isLocalOnlyBypassableByManageScope function in routeGuard.ts checks these values. If you need remote authenticated access to a local-capable endpoint while keeping requireLogin optional, add its prefix to the bypass list.
Summary
- OmniRoute uses a three-tier authorization model (Local-Only, Always-Protected, Management) defined in
src/server/authz/routeGuard.ts. - The
requireLoginflag insrc/lib/db/settings.tscontrols whether management routes require authentication; changes apply live viasrc/lib/config/runtimeSettings.ts. - When
requireLoginisfalse, routes not listed inALWAYS_PROTECTED_API_PATHSaccept unauthenticated requests. - Add critical endpoints to
ALWAYS_PROTECTED_API_PATHSto enforce authentication regardless of the runtime setting. - Use
localOnlyManageScopeBypassEnabledandlocalOnlyManageScopeBypassPrefixesto allow remote authenticated access to local-only routes via management API keys.
Frequently Asked Questions
How do I completely disable authentication in OmniRoute?
Set requireLogin to false in src/lib/db/settings.ts (line 63). This allows anonymous access to all management-tier routes while preserving protection for always-protected paths and maintaining local-only restrictions. Destructive endpoints like /api/shutdown will still reject unauthenticated requests.
What is the difference between local-only and always-protected routes?
Local-only routes block remote connections entirely based on network interface, regardless of credentials, to prevent remote code execution. Always-protected routes accept remote connections but mandate valid authentication even when requireLogin is disabled, protecting destructive operations like database modifications or server shutdown.
How do I make a custom route permanently require authentication?
Add the route path to the ALWAYS_PROTECTED_API_PATHS array in src/server/authz/routeGuard.ts. The isAlwaysProtectedPath function automatically enforces authentication on these endpoints regardless of the global requireLogin setting.
Can remote users access local-only routes with special permissions?
Yes. When localOnlyManageScopeBypassEnabled is true (default), remote clients presenting a valid management-scope API key can access routes matching prefixes in localOnlyManageScopeBypassPrefixes (default: ["/api/mcp/"]). This bypass is evaluated by isLocalOnlyBypassableByManageScope before the local-only check rejects the request.
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 →