How to Configure the Prompt Injection Guard in the OmniRoute Request Pipeline

Enable the prompt injection guard in OmniRoute by setting the INJECTION_GUARD_MODE feature flag to flag or block, and wrap your API routes with the withInjectionGuard middleware exported from src/middleware/promptInjectionGuard.ts.

OmniRoute is an open-source LLM routing layer that protects its endpoints from malicious prompt-injection attacks through a configurable guard system. You can configure the prompt injection guard globally via feature flags or override it per request, giving you fine-grained control over how the pipeline handles potentially malicious content. This guide walks through the source code implementation and configuration options available in the diegosouzapw/OmniRoute repository.

Where the Guard Lives in the Source Code

The prompt injection guard is split across three core components in the OmniRoute codebase.

Middleware Facade

The entry point is src/middleware/promptInjectionGuard.ts, which exports two key functions: createInjectionGuard and the higher-order withInjectionGuard. This middleware intercepts POST, PUT, and PATCH requests, clones the incoming Request object, parses the JSON body, and delegates to the guard-rail evaluator. If the guard blocks the request, it returns an HTTP 400 error immediately.

Detection Engine

The actual security logic resides in src/lib/guardrails/promptInjection.ts. The evaluatePromptInjection function inspects the payload, runs detection rules, and returns a result object containing detections, piiDetections, and a flagged boolean. Based on the current mode, it decides whether to block, flag, or allow the request to proceed.

Registry and Feature Flags

Guard-rail resolution happens in src/lib/guardrails/registry.ts, which checks for the x-omniroute-disabled-guardrails header to determine if the guard should be skipped. The behavior is driven by the INJECTION_GUARD_MODE feature flag defined in src/shared/constants/featureFlagDefinitions.ts at line 41, which supports three values: off, flag, and block.

Configuration Modes and Options

You can configure the guard's behavior at three levels: global feature flags, per-request overrides, and HTTP headers.

Global Feature Flag (Database)

Set the INJECTION_GUARD_MODE value in the feature_flags database table to control the default behavior across all protected routes:

  • off – The guard is completely disabled and all requests pass through.
  • flag – Requests are allowed but the response includes X-Injection-Flagged: true headers and detection counts.
  • block – Malicious requests are rejected with a JSON error (HTTP 400) and error code SECURITY_001.

Changes take effect immediately because the guard reads this flag on every request.

Per-Request Override

When wrapping a route with withInjectionGuard, pass a custom PromptInjectionGuardrailOptions object to override the global setting for that specific endpoint:

export const POST = withInjectionGuard(handler, {
  mode: "block",  // Forces blocking regardless of global flag
  logger: customLogger,
});

This is useful for high-risk endpoints like the chat completions API where you always want strict blocking.

Disable via Header

For internal tooling or trusted clients, disable the guard for a single request by including the header:

x-omniroute-disabled-guardrails: promptInjection

The registry checks this header in src/lib/guardrails/registry.ts and skips evaluation if the guard is listed.

Implementing the Guard in Your Routes

To protect an API endpoint, import the middleware from the source and wrap your handler function.

Basic Route Protection

Wrap your Next.js or Express route handler with withInjectionGuard:

// src/app/api/v1/chat/completions/route.ts
import { withInjectionGuard } from "@/middleware/promptInjectionGuard";

export const POST = withInjectionGuard(async (req, ctx, body) => {
  // body is pre-parsed JSON from the guard
  const response = await handleChat(body);
  return new Response(JSON.stringify(response), {
    status: 200,
    headers: { "Content-Type": "application/json" },
  });
});

The middleware clones the request body and passes it as the third argument (body), so your handler receives already-parsed JSON.

Endpoint-Specific Configuration

Force flag-only mode for specific endpoints that need monitoring but cannot tolerate blocking:

// src/app/api/v1/responses/route.ts
import { withInjectionGuard } from "@/middleware/promptInjectionGuard";

export const POST = withInjectionGuard(async (req, ctx, body) => {
  const result = await handleResponses(body);
  return new Response(JSON.stringify(result), { status: 200 });
}, { mode: "flag" });

Temporary Bypass via curl

Test your API with the guard disabled using the header override:

curl -X POST https://api.example.com/v1/chat/completions \
  -H "x-omniroute-disabled-guardrails: promptInjection" \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-4","messages":[{"role":"user","content":"test"}]}'

How the Pipeline Processes Requests

Understanding the execution flow helps debug configuration issues.

  1. Request Interception – withInjectionGuard creates a guard instance and checks if the request method is POST, PUT, or PATCH. Other methods bypass the guard automatically.

  2. Body Parsing – The middleware clones the incoming Request and parses the JSON payload. If the body was already consumed by upstream middleware, the guard fails.

  3. Registry Check – The system checks src/lib/guardrails/registry.ts for the x-omniroute-disabled-guardrails header. If promptInjection is listed, evaluation is skipped.

  4. Evaluation – evaluatePromptInjection in src/lib/guardrails/promptInjection.ts inspects the payload and reads the current INJECTION_GUARD_MODE value.

  5. Decision – Based on the mode:

    • Block: Returns HTTP 400 with a detailed error object.
    • Flag: Adds X-Injection-Flagged and X-Injection-Detections headers to the response.
    • Allow: Passes the sanitized body to the original handler.
  6. Logging – The guard logs any blocked requests or errors via the configured logger (defaulting to console).

Summary

  • Configure the prompt injection guard globally by setting the INJECTION_GUARD_MODE feature flag in the database to off, flag, or block.
  • Wrap API routes with withInjectionGuard from src/middleware/promptInjectionGuard.ts to enable protection.
  • Override the global mode per endpoint by passing { mode: "block" | "flag" | "off" } options to the middleware.
  • Bypass the guard for specific requests using the x-omniroute-disabled-guardrails: promptInjection header.
  • The guard only processes POST, PUT, and PATCH requests; GET endpoints are not protected.

Frequently Asked Questions

What is the difference between flag and block mode?

Flag mode allows the request to proceed to the LLM but adds response headers (X-Injection-Flagged: true) indicating that the content triggered detection rules. Block mode immediately returns an HTTP 400 response with error code SECURITY_001 and prevents the request from reaching the model. Use flag mode for monitoring and block mode for production protection.

Can I disable the guard for specific requests?

Yes. Add the HTTP header x-omniroute-disabled-guardrails: promptInjection to your request. The registry in src/lib/guardrails/registry.ts checks this header and skips injection evaluation for that specific request, regardless of the global feature flag setting.

Why is my prompt injection guard not blocking requests?

First, verify that INJECTION_GUARD_MODE is set to block in the feature_flags table, not flag or off. Second, ensure your route handler is actually wrapped with withInjectionGuard. Third, check that no upstream middleware is consuming the request body before the guard runs, as this prevents the guard from cloning the payload. Finally, confirm that the x-omniroute-disabled-guardrails header is not present in the request.

Does the guard protect GET requests?

No. According to the implementation in src/middleware/promptInjectionGuard.ts, the guard only activates for POST, PUT, and PATCH requests. GET requests typically do not carry prompt payloads in the request body, so they bypass the injection guard automatically. If you need to validate query parameters, you must implement separate validation logic.

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 →