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 entirelylow— Minimal blocking (high threshold)medium— Balanced protectionhigh— 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_MODEflag controls deployment sensitivity vialow/medium/high/offsettings. - Detection relies on
evaluatePromptInjection()insrc/lib/guardrails/promptInjection.ts, which normalizes patterns, scans payloads, and applies thresholds. - The
promptInjectionGuardmiddleware 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →