How OmniRoute Handles Prompt Injection Guardrails: Architecture, Detection, and Configuration

OmniRoute protects LLM endpoints against prompt-injection attacks using a layered guardrail system integrated directly into the request-handling pipeline, with configurable modes, regex-based pattern detection, and middleware enforcement across all API routes.

OmniRoute is an open-source LLM routing platform that implements defense-in-depth against prompt injection through code-level guardrails. This article explains how the system detects, evaluates, and blocks adversarial prompts based on the v3.8.50 source code.

Guardrail Architecture Overview

OmniRoute's prompt injection protection operates across five integrated layers:

Layer Purpose Source Location
Feature-flag control Toggle protection per-deployment src/shared/constants/featureFlagDefinitions.ts#L41
Pattern detection Regex-based signature matching src/lib/guardrails/promptInjection.ts#L31
Threshold evaluation Configurable sensitivity levels src/lib/guardrails/promptInjection.ts#L109
Middleware integration Route-level enforcement src/middleware/promptInjectionGuard.ts#L24
Structured logging Observability and incident response src/lib/guardrails/promptInjection.ts#L221

The guardrail is best-effort by design—it targets known injection signatures rather than claiming complete adversarial robustness.

Feature Flag Configuration

The INJECTION_GUARD_MODE flag controls deployment-wide behavior. Defined in src/shared/constants/featureFlagDefinitions.ts at line 41, it accepts four values:

  • off — Guard disabled entirely
  • low — Minimal blocking (high threshold)
  • medium — Balanced protection
  • high — Aggressive blocking (low threshold)

The mode also determines whether violations trigger block (HTTP 400) or log-only responses.

Detection Engine: How Patterns Are Evaluated

The core detection logic lives in src/lib/guardrails/promptInjection.ts. The engine processes requests through four distinct stages:

1. Pattern Normalization

The normalizePatternEntry function compiles string or RegExp patterns into case-insensitive, global RegExp objects.

2. Payload Scanning

detectWithPatterns(text, patterns) executes all compiled patterns against request bodies, collecting matches for signatures like "system-prompt" or "ignore above instructions".

3. Threshold Comparison

shouldBlock(detections, threshold) compares match counts against the configured sensitivity level.

4. Decision Rendering

evaluatePromptInjection(options, context, text) produces a PromptInjectionGuardrailDecision with allow or block status.

This architecture enables rapid iteration on detection signatures without modifying route handlers.

Middleware Integration and Request Flow

The promptInjectionGuard middleware in src/middleware/promptInjectionGuard.ts enforces protection uniformly. Line 24 contains the early-return logic that blocks requests before they reach business logic.


Incoming HTTP request
    ↓
Next.js API route (e.g., src/app/api/v1/chat/completions/route.ts)
    ↓
promptInjectionGuard middleware
    ├── evaluatePromptInjection(...)
    ├── if blocked → buildErrorBody(400, "Request blocked: ...")
    └── else → continue to handler
    ↓
Provider request execution

Every LLM endpoint—including /v1/chat/completions, /v1/completions, and image-edit routes—imports this middleware. The chat completions route at src/app/api/v1/chat/completions/route.ts#L176 demonstrates this pattern.

Practical Implementation Examples

Manual Guard Evaluation

For custom processing pipelines, invoke the guard directly:

import { evaluatePromptInjection } from "@/lib/guardrails/promptInjection";
import { getFeatureFlag } from "@/lib/db/featureFlags";

async function checkPromptInjection(reqBody: string) {
  const options = {
    mode: await getFeatureFlag("INJECTION_GUARD_MODE"),
    // Default patterns loaded internally
  };
  const decision = await evaluatePromptInjection(
    options,
    { requestId: "abc123" },
    reqBody
  );
  
  if (decision.block) {
    throw new Error("Prompt injection detected");
  }
  return decision;
}

Adding Protection to New Routes

Apply the middleware to any API endpoint:

import { promptInjectionGuard } from "@/middleware/promptInjectionGuard";
import { handler } from "@/open-sse/handlers/chatCore";

export async function POST(req: Request) {
  // Guard executes first; throws 400 on detection
  await promptInjectionGuard(req);
  
  // Normal processing continues only if allowed
  return handler(req);
}

Observability and Logging

When flagging occurs, the guard emits structured warn-level logs containing:

  • Request ID for correlation
  • Matched pattern signatures
  • Applied enforcement mode

This data at src/lib/guardrails/promptInjection.ts#L221 supports incident response and pattern efficacy analysis.

Key Source Files Reference

File Responsibility
src/lib/guardrails/promptInjection.ts Detection logic, thresholds, logging
src/middleware/promptInjectionGuard.ts Express-style middleware wrapper
src/shared/constants/featureFlagDefinitions.ts INJECTION_GUARD_MODE definition
src/app/api/v1/chat/completions/route.ts Production route integration example
tests/unit/guardrails-registry.test.ts Block-mode behavior validation

Summary

  • OmniRoute implements layered prompt injection guardrails through configurable feature flags, regex pattern detection, threshold-based blocking, and middleware enforcement.
  • The INJECTION_GUARD_MODE flag controls deployment sensitivity via low/medium/high/off settings.
  • Detection relies on evaluatePromptInjection() in src/lib/guardrails/promptInjection.ts, which normalizes patterns, scans payloads, and applies thresholds.
  • The promptInjectionGuard middleware ensures consistent protection across all LLM endpoints including chat completions and image editing routes.
  • Blocked requests return HTTP 400 with sanitized error bodies, while structured logging enables operational monitoring.

Frequently Asked Questions

What prompt injection patterns does OmniRoute detect?

OmniRoute uses the DEFAULT_GUARD_PATTERNS array in src/lib/guardrails/promptInjection.ts to match signatures like "system-prompt", "ignore above instructions", and similar adversarial constructs. These are regular-expression based and compiled with global, case-insensitive flags for robust matching.

Can prompt injection protection be disabled entirely?

Yes. Set INJECTION_GUARD_MODE to off in your feature flag configuration. The flag is defined at src/shared/constants/featureFlagDefinitions.ts#L41 and queried at runtime. Disabling removes all detection overhead but exposes endpoints to injection risks.

How do I add prompt injection protection to a custom route?

Import and call promptInjectionGuard from src/middleware/promptInjectionGuard.ts before your handler logic. The middleware throws an error with HTTP 400 status when injection is detected, halting request processing before your business logic executes.

What's the difference between 'block' and 'log-only' modes?

The mode derives from INJECTION_GUARD_MODE configuration. Block mode returns HTTP 400 to the client immediately. Log-only mode allows the request through while emitting a structured warning log at src/lib/guardrails/promptInjection.ts#L221 for observability without disrupting user experience.

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 →