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:
- Deep-clones the incoming JSON payload
- Walks through user-visible text fields:
system,messages,prompt,input, etc. - Calls
processPII()fromsrc/shared/utils/inputSanitizerfor 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_ENABLEDandPII_RESPONSE_SANITIZATIONflags, both defaulting tofalse - 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-guardrailsheader
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →