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

> Discover OmniRoute's PII masking guardrails. Learn how opt-in redaction protects your LLM traffic by default, ensuring data privacy only when you enable it.

- Repository: [Diego Rodrigues de Sa e Souza/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- Tags: how-to-guide
- Published: 2026-08-04

---

**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`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/promptInjection.ts) |
| **PII-masker guard** | Redacts personal identifiable information in requests and responses—**opt-in only** | [`src/lib/guardrails/piiMasker.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/piiMasker.ts) |
| **Vision-bridge guard** | Validates image payloads (base64 strings, URLs) against expected schemas | [`src/lib/guardrails/visionBridge.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/visionBridge.ts) |

Guardrails are registered at startup via [`src/lib/guardrails/registry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/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`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/base.ts) defines the contract every guardrail follows:

```typescript
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`](https://github.com/diegosouzapw/OmniRoute/blob/main/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`](https://github.com/diegosouzapw/OmniRoute/blob/main/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`](https://github.com/diegosouzapw/OmniRoute/blob/main/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`.

```typescript
// 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

```bash

# 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`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/db/featureFlags.ts):

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

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

```

### Example Request with PII Redaction Active

```bash
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:

```bash
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`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/base.ts) | Abstract base class and type definitions |
| [`src/lib/guardrails/piiMasker.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/piiMasker.ts) | PII masking logic with feature-flag gating |
| [`src/lib/guardrails/promptInjection.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/promptInjection.ts) | Prompt-injection detection |
| [`src/lib/guardrails/registry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/registry.ts) | Runtime guardrail registration |
| [`src/lib/piiSanitizer.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/piiSanitizer.ts) | Response-side PII sanitization |
| [`src/shared/utils/inputSanitizer.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/utils/inputSanitizer.ts) | Core `processPII()` detection logic |
| [`src/shared/constants/featureFlagDefinitions.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/featureFlagDefinitions.ts) | Flag defaults and metadata |
| [`src/lib/db/featureFlags.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/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.