OmniRoute Guardrails and PII Masking: How Opt-In Redaction Protects LLM Traffic

OmniRoute protects every LLM request with an extensible guardrail framework where PII masking is strictly opt-in—guardrails run by default but only redact data when explicitly enabled via feature flags.

The OmniRoute proxy layer includes a lightweight, pluggable guardrail system designed to sanitize, validate, and secure traffic between clients and upstream LLM providers. This article examines the three built-in guardrails in diegosouzapw/OmniRoute and explains precisely how PII masking with opt-in redaction works to prevent accidental data corruption.

OmniRoute Guardrails Overview

All guardrails live in src/lib/guardrails/ and inherit from a common abstract base class. The framework is fail-open: exceptions inside any guardrail are caught, logged, and the request proceeds unmodified.

The Three Built-In Guardrails

Guardrail Purpose Source File
Prompt-injection guard Detects prompt-injection patterns; can log, warn, or block based on INPUT_SANITIZER_MODE src/lib/guardrails/promptInjection.ts
PII-masker guard Redacts personal identifiable information in requests and responses—opt-in only src/lib/guardrails/piiMasker.ts
Vision-bridge guard Validates image payloads (base64 strings, URLs) against expected schemas src/lib/guardrails/visionBridge.ts

Guardrails are registered at startup via src/lib/guardrails/registry.ts and executed by the request pipeline in open-sse/handlers/*.

Base Guardrail Interface

The abstract class in src/lib/guardrails/base.ts defines the contract every guardrail follows:

export abstract class BaseGuardrail {
  constructor(public readonly name: string, public readonly opts: GuardrailOptions) {}
  
  /** Runs before the upstream request is sent. */
  abstract preCall(payload: unknown, ctx: GuardrailContext): Promise<GuardrailResult<unknown>>;
  
  /** Runs after a response is received. */
  abstract postCall(response: unknown, ctx: GuardrailContext): Promise<GuardrailResult<unknown>>;
}

How PII Masking Works

The PII-masker guardrail (PIIMaskerGuardrail) operates in two phases: request-side and response-side masking. Critically, it never mutates payloads unless explicitly enabled.

Request-Side PII Redaction

The preCall() method in src/lib/guardrails/piiMasker.ts invokes cloneAndMaskRequestPayload(), which:

  1. Deep-clones the incoming JSON payload
  2. Walks through user-visible text fields: system, messages, prompt, input, etc.
  3. Calls processPII() from src/shared/utils/inputSanitizer for detection

Actual redaction occurs only when isRequestPiiMaskingEnabled() returns true. This checks the PII_REDACTION_ENABLED feature flag, which defaults to false in src/shared/constants/featureFlagDefinitions.ts.

Response-Side PII Sanitization

After receiving the upstream response, postCall() clones the response and runs sanitizePIIResponse() from src/lib/piiSanitizer.ts. This targets standard response paths like output_text and output[*].content[*].text.

The response-side flag PII_RESPONSE_SANITIZATION also defaults to false.

// From src/shared/constants/featureFlagDefinitions.ts
export const featureFlagDefinitions = {
  PII_REDACTION_ENABLED: { 
    defaultValue: "false", 
    description: "Enable request-side PII redaction" 
  },
  PII_RESPONSE_SANITIZATION: { 
    defaultValue: "false", 
    description: "Enable response-side PII sanitization" 
  },
};

Why Opt-In by Default?

OmniRoute commonly proxies self-hosted or on-premises LLMs where operators fully own their data. Automatic PII redaction risks corrupting legitimate content—code snippets containing phone-number-like strings, for example. The opt-in design preserves data integrity while allowing operators to enable redaction when compliance or privacy requirements demand it.

Enabling PII Redaction

Via Environment Variable


# Enable request-side masking

PII_REDACTION_ENABLED=true

# Enable response-side sanitization

PII_RESPONSE_SANITIZATION=true

Programmatically via Database

For dynamic control, use the feature-flag table in src/lib/db/featureFlags.ts:

import { setFeatureFlag } from '@/lib/db/featureFlags';

await setFeatureFlag('PII_REDACTION_ENABLED', true);
await setFeatureFlag('PII_RESPONSE_SANITIZATION', true);

Example Request with PII Redaction Active

curl http://localhost:20128/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "auto",
    "messages": [
      {"role": "user", "content": "My phone number is 555-123-4567."}
    ]
  }'

With PII_REDACTION_ENABLED=true, the upstream provider receives ***-***-**** instead of the actual number. With PII_RESPONSE_SANITIZATION=true, any PII in the model's reply is similarly masked.

Per-Request Guardrail Bypass

Operators can disable guardrails for individual requests using the x-omniroute-disabled-guardrails header:

curl http://localhost:20128/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "x-omniroute-disabled-guardrails: true" \
  -d '{"model": "auto", "messages": [{"role": "user", "content": "test"}]}'

This header is respected by the guardrail pipeline, enabling temporary opt-out without changing global configuration.

Key Implementation Files

File Purpose
src/lib/guardrails/base.ts Abstract base class and type definitions
src/lib/guardrails/piiMasker.ts PII masking logic with feature-flag gating
src/lib/guardrails/promptInjection.ts Prompt-injection detection
src/lib/guardrails/registry.ts Runtime guardrail registration
src/lib/piiSanitizer.ts Response-side PII sanitization
src/shared/utils/inputSanitizer.ts Core processPII() detection logic
src/shared/constants/featureFlagDefinitions.ts Flag defaults and metadata
src/lib/db/featureFlags.ts Database-backed flag overrides

Summary

  • OmniRoute guardrails are extensible, fail-open protections living in src/lib/guardrails/
  • PII masking is strictly opt-in via PII_REDACTION_ENABLED and PII_RESPONSE_SANITIZATION flags, both defaulting to false
  • The PII-masker guardrail runs unconditionally but returns unmodified payloads when flags are disabled
  • Enable redaction through environment variables or the database-backed flag system
  • Bypass guardrails per-request with the x-omniroute-disabled-guardrails header

Frequently Asked Questions

What happens if a guardrail throws an error?

The guardrail framework is fail-open. Any exception inside preCall() or postCall() is caught, logged, and the request or response continues unchanged. This prevents a misconfigured guardrail from blocking legitimate traffic.

Can I enable only request-side or only response-side PII masking?

Yes. PII_REDACTION_ENABLED controls request-side masking in cloneAndMaskRequestPayload(), while PII_RESPONSE_SANITIZATION controls response-side sanitization in postCall(). These flags operate independently—you can enable either, both, or neither.

Does disabling guardrails with the header also disable PII masking?

Yes. The x-omniroute-disabled-guardrails: true header bypasses all registered guardrails, including the PII-masker. This is useful for debugging or for requests where you know the content is safe and want to avoid any processing overhead.

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 →