OmniRoute Security Measures: Prompt Injection Guard and PII Redaction Explained

OmniRoute implements layered security guardrails including a prompt injection guard with regex-based detection and configurable severity scoring, plus bidirectional PII redaction for both requests and LLM responses, all controlled by runtime feature flags.

OmniRoute (diegosouzapw/OmniRoute) protects AI interactions through a defense-in-depth architecture that scans inbound prompts for malicious instructions and sanitizes sensitive data on both sides of the LLM call. The security system is built around modular guardrails that operators can enable, disable, or tune without code changes. This article examines the implementation details of the prompt injection guard and PII redaction features based on the actual source code.

Prompt Injection Guard Architecture

The prompt injection guard operates as middleware that intercepts requests before they reach the LLM provider.

Core Components

Three files collaborate to provide injection protection:

How the Guard Evaluates Requests

  1. Body parsing: The middleware (createInjectionGuard) parses the request and extracts message content
  2. Pattern matching: evaluatePromptInjection runs built-in regexes (system_override_inline, system_prompt_leak) plus any custom patterns
  3. Severity scoring: Detections are scored as low/medium/high using utilities from src/shared/utils/injectionSeverity.ts
  4. Action determination: Based on INJECTION_GUARD_MODE (warn, block, or log) and the block threshold, the request is logged, flagged, or rejected with HTTP 400

The scan is performance-bounded: only the first 16 KiB (MAX_INJECTION_SCAN_BYTES) of the concatenated prompt is examined to keep the hot path fast.

Middleware Integration Example

// src/app/api/v1/chat/completions/route.ts
import { withInjectionGuard } from "@/middleware/promptInjectionGuard";
import { handleChatCore } from "@/open-sse/handlers/chatCore";

export const POST = withInjectionGuard(async (request, _, parsedBody) => {
  const payload = parsedBody ?? await request.json();
  return handleChatCore(payload);
});

When blocking occurs, the middleware returns:

{
  "type": "injection_detected",
  "code": "SECURITY_001",
  "message": "Prompt injection patterns detected"
}

HTTP headers X-Injection-Flagged and X-Injection-Detections are always added for downstream observability.

Custom Pattern Support

Operators can extend detection at runtime without modifying core code:

import { PromptInjectionGuardrail } from "@/lib/guardrails/promptInjection";

const guard = new PromptInjectionGuardrail({
  customPatterns: [
    { 
      name: "proprietary_token_leak", 
      pattern: /sk-[a-zA-Z0-9]{32,}/i, 
      severity: "high" 
    },
  ],
});
await guard.preCall(requestBody, { log: console });

Custom patterns merge with DEFAULT_GUARD_PATTERNS and receive identical severity scoring.

PII Redaction System

OmniRoute provides bidirectional PII protection: sanitizing user inputs before they reach the LLM, and scrubbing LLM outputs before they reach users.

Request-Side PII Masking

Implementation: src/lib/guardrails/piiMasker.ts and processPII in src/shared/utils/inputSanitizer.ts

The request-side mask checks the feature flag PII_REDACTION_ENABLED (read from database → environment → default). When enabled, every string field in the payload is scanned against PII_PATTERNS and replaced with typed placeholders.

Pattern Placeholder Validation
Email [EMAIL_REDACTED] RFC 5322 regex
Credit card [CC_REDACTED] Luhn checksum via isValidLuhn()
CPF (Brazilian) [CPF_REDACTED] Modulo 11 algorithm
CNPJ (Brazilian) [CNPJ_REDACTED] Weighted digit validation
SSN [SSN_REDACTED] Format XXX-XX-XXXX
IPv4/IPv6 [IP_REDACTED] Standard patterns
Phone numbers [PHONE_REDACTED] E.164 variants
AWS keys [AWS_KEY_REDACTED] AKIA/ASIA prefixes
Generic API keys [API_KEY_REDACTED] Heuristic patterns

The mask returns detection counts for audit logging.

Response-Side PII Sanitization

Implementation: src/lib/piiSanitizer.ts

The response sanitizer is invoked by the post-call step of PIIMaskerGuardrail. It walks JSON responses recursively, applying the same regex set with four operating modes controlled by PII_RESPONSE_SANITIZATION_MODE:

  • redact — Replace matches with placeholders (default)
  • warn — Log detections without modification
  • block — Abort request with error
  • off — Disable processing

Streaming Response Handling

For streaming responses, sanitizePIIChunk handles partial buffers safely. A match ending at a chunk boundary is deferred until the next chunk arrives (endMatchIndex handling) to prevent premature redaction of incomplete tokens.

Manual PII Sanitization

import { sanitizePII } from "@/lib/piiSanitizer";

const raw = "Contact: john.doe@company.com, Card: 4532-0151-1283-0356";
const { text, detections, redacted } = sanitizePII(raw);

console.log(text);
// "Contact: [EMAIL_REDACTED], Card: [CC_REDACTED]"

console.log(detections);
// [
//   { pattern: "email", count: 1, severity: "medium" },
//   { pattern: "credit_card", count: 1, severity: "high" }
// ]

Feature Flag Control System

All security guards are runtime-configurable through src/shared/utils/featureFlags.ts. The resolution order is:

  1. Database table feature_flags (highest priority)
  2. Environment variables
  3. Hardcoded defaults

Key Environment Variables


# Request-side controls

PII_REDACTION_ENABLED=true
INPUT_SANITIZER_ENABLED=true

# Injection guard

INJECTION_GUARD_MODE=block   # warn | block | log

# Response-side controls

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

This design allows security posture changes without deployment, supporting gradual rollouts and incident response.

Audit Logging and Observability

Both guardrails integrate with GuardrailContext.log:

Severity Event Type Log Level
High-confidence injection Blocked request warn
Medium confidence injection Flagged request info
PII detection (redact mode) Sanitization applied debug
PII detection (block mode) Aborted response warn

Log metadata includes pattern names, severity scores, detection counts, and request correlation IDs.

Configuration Best Practices

For production deployments of OmniRoute, consider this security layering:

  1. Enable request-side PII redaction (PII_REDACTION_ENABLED=true) to prevent user data leakage to LLM providers
  2. Set injection guard to block mode for high-risk endpoints; use warn mode during initial rollout to assess false positive rates
  3. Enable response-side sanitization when LLMs may echo training data or generate realistic-looking fake credentials
  4. Customize patterns for domain-specific secrets (internal API prefixes, proprietary formats) via the customPatterns API

Summary

  • Prompt injection guard: Regex-based detection with severity scoring, configurable modes (warn/block/log), 16 KiB scan limit, and custom pattern support via src/lib/guardrails/promptInjection.ts
  • PII redaction: Bidirectional sanitization with checksum-validated patterns (Luhn for cards, modulo 11 for Brazilian IDs), streaming-safe chunk processing, and typed placeholders
  • Runtime control: Database-backed feature flags with environment fallbacks for zero-code security adjustments
  • Observability: Structured logging with HTTP headers for downstream telemetry

Frequently Asked Questions

How does OmniRoute's prompt injection guard differ from simple input validation?

The guard uses multi-pattern regex matching with severity scoring rather than binary allow/block lists. It evaluates detections against configurable thresholds (shouldBlockDetections), supports custom patterns at runtime, and provides graduated responses (log/warn/block) based on INJECTION_GUARD_MODE. The 16 KiB scan limit ensures low latency even on large prompts.

Can PII redaction handle streaming responses without corrupting JSON?

Yes. The sanitizePIIChunk function in src/lib/piiSanitizer.ts tracks endMatchIndex to defer redaction of partial matches at chunk boundaries. This prevents false replacements when a sensitive token spans multiple chunks, maintaining valid JSON structure throughout the stream.

What happens if both injection detection and PII redaction trigger on the same request?

Processing occurs in sequence: PII redaction runs first on the request body (if enabled), then the sanitized content is evaluated for prompt injection. If injection is detected and mode is block, the request fails with SECURITY_001 before reaching the LLM. Both detections are logged independently with their respective pattern metadata.

Is checksum validation applied to all PII patterns?

No. Luhn validation (isValidLuhn) and Brazilian ID algorithms apply only to credit cards, CPF, and CNPJ where mathematical verification reduces false positives. Other patterns (email, IP, phone) rely on regex matching alone. The pattern definitions in PII_PATTERNS specify which validators to invoke.

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 →