Setting Up Guardrails for Prompt Injection and PII Redaction in OmniRoute

OmniRoute protects inbound user prompts and outbound LLM responses with a configurable two-layer guardrail system that blocks injection attacks and redacts personally identifiable information.

Setting up guardrails for prompt injection and PII redaction in OmniRoute requires configuring feature flags and applying middleware to your API routes. The repository implements these protections through a modular TypeScript architecture that runs on every request unless explicitly opted out via headers.

Architecture Overview

OmniRoute implements a two-layer guardrail system that operates independently:

  1. Prompt-Injection Guard – Scans incoming request bodies for malicious system-prompt tricks, jailbreaks, and injection patterns
  2. PII Redaction Guard – Detects and strips personally identifiable information from both request payloads and LLM responses

All guardrails are opt-in only by design. According to Hard Rule #20 in the codebase, both PII_REDACTION_ENABLED and PII_RESPONSE_SANITIZATION default to false to prevent silent data loss. The regression test in tests/unit/pii-opt-in-default.test.ts enforces this contract, requiring explicit operator approval to change defaults.

Configuring Prompt-Injection Protection

The injection detection middleware lives in src/middleware/promptInjectionGuard.ts and attaches to routes using either createInjectionGuard or withInjectionGuard.

Middleware Installation

Wrap your API route handlers with the injection guard:

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

export const POST = createInjectionGuard(async (req) => {
  // Your handler logic …
});

For existing handlers, use the wrapper approach:

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

export const POST = withInjectionGuard(async (req) => {
  // Handler …
});

Feature Flag Configuration

Control the guard via environment variables or database overrides:

INPUT_SANITIZER_ENABLED=true
INPUT_SANITIZER_MODE=block  # Options: warn | block | log

The INPUT_SANITIZER_MODE determines behavior when injection patterns are detected:

  • warn – Logs the attempt but forwards the request
  • block – Returns an error response immediately
  • log – Silent logging without blocking or warning

Enabling PII Redaction and Sanitization

PII protection splits between request-side masking (incoming user data) and response-side sanitization (outgoing LLM content).

Request-Side PII Masking

Implemented in src/lib/guardrails/piiMasker.ts, this layer strips PII from user payloads before upstream forwarding:

PII_REDACTION_ENABLED=true

Response-Side PII Sanitization

The response-side implementation spans two files: src/lib/piiSanitizer.ts for standard responses and src/lib/streamingPiiTransform.ts for SSE streams.

Enable via flags:

PII_RESPONSE_SANITIZATION=true
PII_RESPONSE_SANITIZATION_MODE=redact  # Options: redact | warn | block | off

Streaming safety is handled by a sliding-window algorithm in src/lib/streamingPiiTransform.ts that catches PII spanning chunk boundaries, ensuring no leaked data slips through fragmented SSE responses.

Using the SSE Transformer

For streaming endpoints, attach the PII transformer manually:

import { createPiiSseTransform } from "@/lib/streamingPiiTransform";

const transform = createPiiSseTransform(); // attaches to your SSE pipeline

Managing Feature Flags

Feature flags resolve via src/lib/db/featureFlags.ts, allowing database overrides to take precedence over environment variables. This architecture enables runtime configuration changes without redeployment.

The guardrail registry in src/lib/guardrails/registry.ts maintains a centralized list of active guardrails. Debug your configuration by inspecting registered components:

import { guardrailRegistry } from "@/lib/guardrails/registry";

console.log(guardrailRegistry.list()); // shows PIIMaskerGuardrail, etc.

Disabling Guardrails per Request

While there is no persistent UI for enabling or disabling guardrails, individual requests may opt out by sending the header:


x-omniroute-disabled-guardrails: true

This header bypasses all guardrail checks for that specific request.

Implementation Independence

The architecture deliberately decouples injection protection from PII handling. Even when INPUT_SANITIZER_MODE=block, PII redaction remains toggled separately via its own flags. This modularity prevents unintended side effects when adjusting security postures.

Summary

  • Prompt-injection protection attaches via createInjectionGuard or withInjectionGuard in src/middleware/promptInjectionGuard.ts and operates in warn, block, or log modes based on INPUT_SANITIZER_MODE.

  • PII redaction requires explicit opt-in via PII_REDACTION_ENABLED (request-side) and PII_RESPONSE_SANITIZATION (response-side), with defaults set to false to prevent accidental data modification.

  • Streaming responses use src/lib/streamingPiiTransform.ts with a sliding-window algorithm to handle PII detection across chunk boundaries.

  • Feature flags resolve through src/lib/db/featureFlags.ts, supporting both environment variables and dynamic database overrides.

  • Guardrail registry at src/lib/guardrails/registry.ts enables uniform enumeration and invocation of security components.

Frequently Asked Questions

How do I enable prompt injection detection in OmniRoute?

Set INPUT_SANITIZER_ENABLED=true in your environment or database, then wrap your route handlers with createInjectionGuard or withInjectionGuard imported from src/middleware/promptInjectionGuard.ts. Choose a mode via INPUT_SANITIZER_MODE (warn, block, or log) to determine how the system handles detected injection attempts.

What is the difference between request-side and response-side PII redaction?

Request-side redaction occurs in src/lib/guardrails/piiMasker.ts and strips PII from incoming user payloads before they reach the LLM. Response-side redaction, implemented in src/lib/piiSanitizer.ts and src/lib/streamingPiiTransform.ts, scans LLM outputs for leaked PII before sending them to the client. Both are controlled by separate feature flags (PII_REDACTION_ENABLED vs PII_RESPONSE_SANITIZATION).

Can I disable guardrails for specific requests?

Yes. Send the header x-omniroute-disabled-guardrails with your request to bypass all guardrail checks for that transaction. However, there is no persistent UI or global disable switch—configuration changes require modifying environment variables or database feature flags.

Why are PII guardrails disabled by default in OmniRoute?

PII redaction defaults to false (Hard Rule #20) to prevent silent data loss. Automatically stripping PII could inadvertently remove critical information that operators or users expect to preserve. The regression test in tests/unit/pii-opt-in-default.test.ts enforces this requirement, ensuring operators explicitly acknowledge the payload-modifying implications of enabling PII sanitization.

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 →