How OmniRoute Guardrails Handle PII Redaction and Prompt Injection Detection

OmniRoute protects user data and model integrity through two dedicated guardrails: an opt-in PII Masker that redacts personal data in requests and responses, and a Prompt Injection Guardrail that scans for malicious patterns with configurable block thresholds and enforcement modes.

OmniRoute's guardrail architecture provides defense-in-depth for production LLM deployments, ensuring sensitive information never leaks upstream while blocking attempts to manipulate system prompts. The system is implemented in TypeScript and integrates directly into the request pipeline through specialized middleware.

PII Redaction: Opt-In Masking for Requests and Responses

The PII Masker Guardrail (src/lib/guardrails/piiMasker.ts) provides comprehensive personal data protection through a cloning-and-scanning approach that preserves the original payload structure.

How PII Redaction Works

The guardrail processes every request and response through three stages:

  1. Payload cloning – Creates a deep copy to avoid mutating the original request
  2. Field traversal – Walks all string fields including system, messages, and prompts
  3. Pattern execution – Runs processPII across all text, collecting detections

If any text is altered, the sanitized payload replaces the original before upstream transmission. Responses undergo identical treatment via sanitizePII and sanitizePIIResponse methods.

Feature Flag Control

Redaction is controlled by isRequestPiiMaskingEnabled(), which checks a database override first, then falls back to the PII_REDACTION_ENABLED environment variable:

// In .env (or via DB UI)
PII_REDACTION_ENABLED=true

This opt-in design ensures zero performance impact when disabled and gives operators granular control per deployment.

Prompt Injection Detection: Static Pattern Scanning with Severity Scoring

The Prompt Injection Guardrail (src/lib/guardrails/promptInjection.ts) combines fast pattern matching with flexible enforcement modes to stop malicious directives before they reach the model.

Detection Pipeline

The guardrail executes a capped scan sequence optimized for latency:

// Simplified flow based on src/lib/guardrails/promptInjection.ts
1. Check INPUT_SANITIZER_ENABLED global flag
2. Extract full textual content via extractMessageContents()
3. Run pattern scan (capped at MAX_INJECTION_SCAN_BYTES)
4. Score detections using SHARED_SEVERITY_SCORES
5. Apply resolved mode: 'block' | 'warn' | 'log'

Pattern Sources and Severity

The guardrail evaluates against built-in defaults and user-supplied custom patterns:

  • system_override_inline – Inline attempts to override system behavior
  • markdown_system_block – Hidden system instructions in markdown formatting
  • Custom patterns via configuration object

Each pattern carries a severity level (low, medium, high, critical) that feeds into the scoring decision.

Enforcement Modes

The resolved mode determines the guardrail's response:

Mode Behavior Use Case
block Return 400 error, halt execution Production with strict security
warn Log detection, allow request Staged rollouts, monitoring
log Silent recording only Telemetry and analysis

Mode resolution follows the same priority as PII: database override (INJECTION_GUARD_MODE) → environment variable → default.

Middleware Integration: Wiring Guardrails into the Request Pipeline

Both guardrails connect to API routes through the Prompt-Injection Middleware (src/middleware/promptInjectionGuard.ts), which provides two integration patterns.

Automatic Guard with withInjectionGuard

The standard approach wraps route handlers with automatic evaluation:

import { withInjectionGuard } from "@/middleware/promptInjectionGuard";

export async function POST(req: Request) {
  // The guard will automatically evaluate and possibly block the request
  return withInjectionGuard(req, async (sanitizedBody) => {
    // Your normal handler logic here – `sanitizedBody` is already PII‑masked
    return handleChatCore(sanitizedBody);
  });
}

Custom Guard Instance with createInjectionGuard

For routes requiring specific detection rules, create a configured instance:

import { createInjectionGuard } from "@/middleware/promptInjectionGuard";

const guard = createInjectionGuard({
  customPatterns: [{ 
    name: "custom_sql", 
    pattern: /SELECT\s+.*\s+FROM/i, 
    severity: "high" 
  }],
  blockThreshold: "medium",
  mode: "block",
});

export async function POST(req: Request) {
  return guard(req, async (sanitizedBody) => {
    return handleChatCore(sanitizedBody);
  });
}

Structured Decision Objects

Both approaches return a unified decision structure:

  • blocked – Boolean indicating halt status
  • detections – Prompt injection findings with severity scores
  • piiDetections – Personal data matches found and replaced

Blocked requests receive immediate 400-series responses without reaching the provider executor.

Key Implementation Files

Understanding the complete system requires examining these source files:

Summary

  • PII redaction is opt-in via PII_REDACTION_ENABLED, implemented by cloning and scanning all string fields in src/lib/guardrails/piiMasker.ts
  • Prompt injection detection uses fast, byte-capped pattern scanning with configurable block, warn, and log modes in src/lib/guardrails/promptInjection.ts
  • Both guardrails integrate through src/middleware/promptInjectionGuard.ts using withInjectionGuard or createInjectionGuard patterns
  • Enforcement decisions combine database overrides with environment fallbacks for operational flexibility
  • Custom patterns and thresholds allow per-route security tailoring without code duplication

Frequently Asked Questions

How do I enable PII redaction in OmniRoute?

Set PII_REDACTION_ENABLED=true in your environment configuration or toggle the feature flag through the database UI. The isRequestPiiMaskingEnabled() function in src/shared/utils/featureFlags.ts checks the database override first, then the environment variable, allowing runtime configuration changes without restarts.

What prompt injection patterns does OmniRoute detect by default?

The guardrail includes built-in patterns for common attacks like system_override_inline and markdown_system_block. The full pattern set is extensible through the customPatterns option in createInjectionGuard, where you supply regex patterns with assigned severity levels for domain-specific threats.

Can I use different enforcement modes for different API routes?

Yes. While the global default comes from INJECTION_GUARD_MODE or its environment equivalent, the createInjectionGuard factory accepts a mode parameter that overrides this for specific routes. This enables stricter blocking on public endpoints while using warn mode for internal tooling.

What happens when a request triggers both PII detection and prompt injection?

The middleware executes both guardrails sequentially. PII masking applies first, sanitizing the payload content. Then prompt injection scanning evaluates the (potentially already-masked) text. If injection is detected and mode is block, the request halts with a 400 error regardless of PII findings. Both detection sets appear in the structured decision object for logging and audit purposes.

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 →