How OmniRoute Handles Prompt Injection Guardrails: A Layered Defense Architecture

OmniRoute protects its LLM endpoints against prompt injection attacks using a configurable, multi-layer guardrail system built directly into the request-handling pipeline.

This open-source routing layer for LLM providers implements defense-in-depth against prompt injection through pattern-based detection, configurable thresholds, and middleware enforcement. According to the OmniRoute source code, the guardrail system is designed as a best-effort mechanism that balances security with legitimate traffic flow.

Guardrail Architecture Overview

The prompt injection defense consists of five integrated layers, each implemented in specific source files across the codebase.

Feature-Flag Control

Deployments toggle guard behavior via the INJECTION_GUARD_MODE flag defined in src/shared/constants/featureFlagDefinitions.ts#L41. Valid values are:

  • off — disables detection entirely
  • low — permissive threshold, minimal pattern matches required
  • medium — balanced detection sensitivity
  • high — strict threshold, maximum pattern matches required

This flag enables gradual rollouts and environment-specific configurations without code changes.

Pattern Detection Engine

The core detection logic lives in src/lib/guardrails/promptInjection.ts#L31. The DEFAULT_GUARD_PATTERNS array contains regular-expression signatures targeting common injection constructs:

  • Phrases like "system-prompt" or "ignore above instructions"
  • Delimiter manipulation attempts
  • Instruction override patterns

Patterns are normalized with global and case-insensitive flags via normalizePatternEntry(), then compiled for efficient reuse.

Threshold Evaluation and Modes

Detection results are evaluated against the configured threshold in src/lib/guardrails/promptInjection.ts#L109. The system supports two operational modes:

  • Block mode — requests exceeding threshold receive HTTP 400 with sanitized error body
  • Log-only mode — detections are recorded but request proceeds normally

Mode selection derives from the feature flag, allowing passive monitoring before active enforcement.

Middleware Integration

The src/middleware/promptInjectionGuard.ts#L24 file implements Express-style middleware that wraps the evaluation logic. When triggered, buildErrorBody(400, "Request blocked: …") returns a generic response that leaks no internal pattern details to potential attackers.

Route-Level Deployment

Every LLM endpoint imports this middleware, as shown in src/app/api/v1/chat/completions/route.ts#L176. Coverage extends to:

  • /v1/chat/completions
  • /v1/completions
  • Image generation and editing endpoints

This guarantees consistent protection across the entire API surface without per-route reimplementation.

Detection Pipeline: How Evaluation Works

The prompt injection guard follows a four-stage pipeline for each request:

  1. NormalizationnormalizePatternEntry() converts string or RegExp patterns into compiled, case-insensitive global expressions.

  2. ScanningdetectWithPatterns(text, patterns) executes all compiled patterns against the request payload, aggregating matches into a detection array.

  3. Threshold evaluationshouldBlock(detections, threshold) compares match count against the low/medium/high threshold derived from the feature flag.

  4. DecisionevaluatePromptInjection(options, context, text) synthesizes mode, threshold, and enabled status into a PromptInjectionGuardrailDecision object with allow or block outcome.

Observability and Logging

When detection triggers, src/lib/guardrails/promptInjection.ts#L221 emits structured logs at warn level containing:

  • Request ID for correlation
  • Matched pattern identifiers
  • Applied operational mode

This supports incident response and false-positive analysis without exposing detection internals.

Request Flow Diagram


Incoming HTTP request
        ↓
Next.js API route (e.g., src/app/api/v1/chat/completions/route.ts)
        ↓
promptInjectionGuard middleware 
        │
        ├─ evaluatePromptInjection(...)
        ├─ if block → buildErrorBody(400, "Request blocked: …")
        └─ else → continue to handler
        ↓
Handler executes provider request (open-sse/... executors)

All production routes follow this pattern, establishing uniform enforcement.

Implementation Examples

Manual Guard Evaluation

Use the core function directly for custom processing pipelines:

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"),
    // guard uses DEFAULT_GUARD_PATTERNS internally
  };
  const decision = await evaluatePromptInjection(
    options,
    { requestId: "abc123" },
    reqBody
  );
  if (decision.block) {
    throw new Error("Prompt injection detected");
  }
  return decision;
}

Middleware Integration in New Routes

Add protection to custom endpoints with minimal boilerplate:

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

export async function POST(req: Request) {
  // Guard runs first; throws 400 if injection detected
  await promptInjectionGuard(req);
  // Normal processing continues
  return handler(req);
}

Key Source Files

File Purpose
[src/lib/guardrails/promptInjection.ts](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/src/lib/guardrails/promptInjection.ts) Core detection, threshold logic, logging
[src/middleware/promptInjectionGuard.ts](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/src/middleware/promptInjectionGuard.ts) HTTP middleware wrapper
[src/shared/constants/featureFlagDefinitions.ts](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/src/shared/constants/featureFlagDefinitions.ts) INJECTION_GUARD_MODE flag definition
[src/app/api/v1/chat/completions/route.ts](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/src/app/api/v1/chat/completions/route.ts) Production route integration example
[tests/unit/guardrails-registry.test.ts](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/tests/unit/guardrails-registry.test.ts) Validation test suite

Limitations and Design Rationale

The guardrail system is explicitly best-effort. It targets known injection signatures rather than attempting complete adversarial robustness. This trade-off acknowledges:

  • The computational cost of deep semantic analysis
  • The evolving nature of prompt injection techniques
  • The need to preserve latency for legitimate requests

The test suite in guardrails-registry.test.ts verifies that "suspicious content in block mode" is rejected while normal traffic flows unimpeded.

Summary

  • OmniRoute implements prompt injection guardrails through a layered architecture combining feature flags, regex pattern detection, configurable thresholds, and middleware enforcement.

  • Detection occurs in src/lib/guardrails/promptInjection.ts using normalized patterns against request payloads, with decisions rendered by evaluatePromptInjection().

  • Enforcement is universal via promptInjectionGuard middleware applied to all LLM endpoints including chat completions and image routes.

  • Operational flexibility allows low/medium/high sensitivity levels and block/log-only modes without deployment changes.

  • Observability is built-in through structured logging of detections with request IDs for downstream analysis.

Frequently Asked Questions

How do I disable prompt injection detection in OmniRoute?

Set the INJECTION_GUARD_MODE feature flag to off in your deployment configuration. This flag is defined in src/shared/constants/featureFlagDefinitions.ts and read at request time via getFeatureFlag(). The change takes effect immediately without restarting services.

What patterns does OmniRoute use to detect prompt injection?

The system uses the DEFAULT_GUARD_PATTERNS array in src/lib/guardrails/promptInjection.ts, which includes signatures for common attack vectors like "ignore previous instructions" and "system prompt override" phrases. These are regular expressions normalized for case-insensitive matching.

Can I add custom detection patterns to the guardrail?

The source-defined DEFAULT_GUARD_PATTERNS is currently fixed, but you can extend detection by wrapping evaluatePromptInjection() with additional pattern matching before or after the built-in evaluation. Custom implementations should follow the same normalization pattern using normalizePatternEntry().

Does prompt injection detection impact API latency?

The regex-based scanning adds minimal overhead for typical request sizes. Pattern compilation occurs at initialization, not per-request. For latency-sensitive deployments, log-only mode permits detection without blocking delays, or the guard can be disabled entirely via feature flag.

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 →