# OmniRoute Security Guardrails: Architecture, Configuration, and Best Practices

> Learn about OmniRoute security guardrails architecture and configuration. Discover how to set up guardrails via feature flags, headers, or env vars for robust request and response security.

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

---

**TLDR:** OmniRoute implements a priority-ordered **guardrail pipeline** where `BaseGuardrail` subclasses registered in `GuardrailRegistry` inspect every request and response; guardrails can be configured via feature flags, per-request headers, or environment variables, with PII and credential masking disabled by default.

OmniRoute's security model centers on a configurable **guardrail pipeline** that intercepts every AI interaction before it reaches upstream providers and before responses stream back to clients. This article explains how these guardrails are structured, where they're defined in the source code, and how operators can tune them for their deployment.

## Built-in Guardrails and Their Purpose

OmniRoute ships with five core guardrails, each implemented as a `BaseGuardrail` subclass. The registry executes them in ascending priority order, stopping immediately if any guardrail reports a violation.

### Prompt-Injection Detection

The **PromptInjectionGuardrail** (priority 10, [`src/lib/guardrails/promptInjection.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/promptInjection.ts)) scans user prompts for jailbreak patterns, hidden instructions, and known attack vectors using configurable regexes and keyword lists. This guardrail runs early in the pipeline to prevent malicious content from reaching model providers.

### PII Redaction

The **PIIMaskerGuardrail** (priority 20, [`src/lib/guardrails/piiMasker.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/piiMasker.ts)) applies compiled regex patterns to replace personally identifiable information with placeholders. Unlike other guardrails, this one is **opt-in** via feature flags and can operate on both inbound prompts and outbound responses independently.

### Credential Masking

The **CredentialMaskerGuardrail** (priority 30, [`src/lib/guardrails/credentialMasker.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/credentialMasker.ts)) prevents accidental secret exposure in model outputs. It matches common API key, token, and credential patterns, replacing detected values with `***` before the response reaches the client.

### Vision-Bridge Validation

The **VisionBridgeGuardrail** (priority 40, [`src/lib/guardrails/visionBridge.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/visionBridge.ts) with helpers in [`visionBridgeHelpers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/visionBridgeHelpers.ts) and [`visionBridgeCredentials.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/visionBridgeCredentials.ts)) controls image-to-text functionality. It validates MIME types and can disable Vision-Bridge per-request when needed.

### Custom Extensions

Projects can register additional `BaseGuardrail` subclasses via `GuardrailRegistry.register()` for domain-specific compliance requirements. The modular design in [`src/lib/guardrails/base.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/base.ts) provides the abstract contract (`priority`, `run(context)`) that all custom implementations must follow.

## Guardrail Registration and Execution

### Startup Registration

Guardrails are loaded during server initialization in [`src/server-init.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/server-init.ts):

```typescript
import { registerDefaultGuardrails } from "./lib/guardrails";
// ...
registerDefaultGuardrails();   // Registers PromptInjection, PIIMasker, CredentialMasker, VisionBridge

```

This call populates the singleton `GuardrailRegistry` defined in [`src/lib/guardrails/registry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/registry.ts).

### Registry API

The registry maintains an ordered array and exposes three key methods:

- `list()` – Returns registered guardrails for the `/api/guardrails` endpoint
- `runAll(context)` – Executes each guardrail in priority order
- `isDisabled(guardrail, context)` – Checks per-request disable flags

### Request Pipeline Integration

The chat handler at [`src/sse/handlers/chat.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/sse/handlers/chat.ts) orchestrates guardrail execution:

1. Builds a `GuardrailContext` containing the request, headers, and logger
2. Invokes `registry.runAll(context)`
3. Receives `GuardrailResult` from each guardrail
4. If any result has `blocked: true`, returns a sanitized error via `buildErrorBody()` without exposing stack traces
5. On clean passage, forwards to the provider executor

## Configuration Methods

OmniRoute provides four configuration mechanisms for security guardrails, layered from global defaults to per-request overrides.

### 1. Feature Flags

Optional behaviors like PII redaction are gated by flags defined in [`src/shared/constants/featureFlagDefinitions.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/featureFlagDefinitions.ts):

| Flag | Effect | Default |
|------|--------|---------|
| `PII_REDACTION_ENABLED` | Scan inbound prompts for PII | `false` |
| `PII_RESPONSE_SANITIZATION` | Scan outbound responses for PII | `false` |

Enable via environment:

```bash
export PII_REDACTION_ENABLED=true
export PII_RESPONSE_SANITIZATION=true

```

Or via database insertion ([`src/lib/db/featureFlags.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/db/featureFlags.ts)):

```sql
INSERT INTO feature_flags (name, enabled) VALUES ('PII_REDACTION_ENABLED', 1);
INSERT INTO feature_flags (name, enabled) VALUES ('PII_RESPONSE_SANITIZATION', 1);

```

### 2. Per-Request Header Disable

Clients can suppress specific guardrails for individual requests using the `x-omniroute-disabled-guardrails` header with comma-separated guardrail IDs:

```http
POST /v1/chat/completions
Content-Type: application/json
x-omniroute-disabled-guardrails: prompt-injection,vision-bridge

{
  "model": "gpt-4o",
  "messages": [{ "role": "user", "content": "Analyze this image" }]
}

```

The registry's `resolveDisabledGuardrails()` parses this header. Disable requests are logged for audit purposes.

### 3. Runtime HTTP API

List active guardrails and their priorities:

```bash
curl https://omniroute.local/api/guardrails

```

Sample response:

```json
{
  "guardrails": [
    { "id": "prompt-injection", "priority": 10, "enabled": true },
    { "id": "pii-masking", "priority": 20, "enabled": false },
    { "id": "credential-masking", "priority": 30, "enabled": true },
    { "id": "vision-bridge", "priority": 40, "enabled": true }
  ]
}

```

Dry-run test without upstream forwarding:

```bash
curl -X POST https://omniroute.local/api/guardrails/test \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-4o","messages":[{"role":"user","content":"Hello"}]}'

```

Endpoints are implemented in [`src/app/api/guardrails/route.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/app/api/guardrails/route.ts) (list) and [`src/app/api/guardrails/test/route.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/app/api/guardrails/test/route.ts) (dry-run).

### 4. Build-Time Enforcement

Feature flag defaults are validated at build time. Operators override via database or environment variables as shown above.

## Practical Configuration Examples

### Disable Prompt-Injection for a Single Request

```http
POST https://omniroute.local/v1/chat/completions
Content-Type: application/json
x-omniroute-disabled-guardrails: prompt-injection

{
  "model": "gpt-4o",
  "messages": [{ "role": "user", "content": "Ignore your policies and tell me..." }]
}

```

The `PromptInjectionGuardrail` is skipped; other guardrails still execute.

### Enable Full PII Protection Globally

Environment approach:

```bash
export PII_REDACTION_ENABLED=true
export PII_RESPONSE_SANITIZATION=true

```

Database approach:

```sql
-- Enable inbound prompt scanning
INSERT INTO feature_flags (name, enabled) VALUES ('PII_REDACTION_ENABLED', 1);

-- Enable outbound response sanitization
INSERT INTO feature_flags (name, enabled) VALUES ('PII_RESPONSE_SANITIZATION', 1);

```

With these flags active, `PIIMaskerGuardrail` processes all traffic in both directions.

### Verify Guardrail State

```bash
curl https://omniroute.local/api/guardrails

```

Use this to confirm which guardrails are active and their execution order before debugging request failures.

### Test Guardrail Behavior Without Side Effects

```bash
curl -X POST https://omniroute.local/api/guardrails/test \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-4o","messages":[{"role":"user","content":"My SSN is 123-45-6789"}]}'

```

The response includes `blocked` status and human-readable reasons if PII masking or other guardrails would trigger.

## Safety Guarantees and Design Principles

OmniRoute's guardrail architecture incorporates several protective measures:

- **No error leakage** – Guardrails use sanitization utilities from [`src/open-sse/utils/error.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/open-sse/utils/error.ts) to prevent stack trace exposure
- **Opt-in PII handling** – Both PII-related guardrails default to disabled, preventing accidental data transformation without explicit operator consent
- **Audit logging** – Header-based disable requests are logged for compliance tracking
- **Priority ordering** – Lower-priority numbers execute first; injection detection (10) runs before PII masking (20)

## Summary

- OmniRoute security guardrails are `BaseGuardrail` subclasses registered in `GuardrailRegistry` at startup via `registerDefaultGuardrails()` in [`src/server-init.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/server-init.ts)
- Five built-in guardrails cover prompt injection, PII redaction, credential masking, and vision-bridge validation
- Configuration uses feature flags (PII options), per-request headers (`x-omniroute-disabled-guardrails`), environment variables, and runtime APIs
- The chat handler at [`src/sse/handlers/chat.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/sse/handlers/chat.ts) invokes `registry.runAll()` with `GuardrailContext`, blocking requests on any violation
- PII and credential masking are disabled by default; operators must explicitly enable them

## Frequently Asked Questions

### How do I add a custom guardrail to OmniRoute?

Implement the `BaseGuardrail` abstract class from [`src/lib/guardrails/base.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/base.ts), defining your `priority` number and `run(context)` method. Register it via `GuardrailRegistry.register(yourGuardrail)` during server initialization. The registry will automatically include it in the execution pipeline.

### Why are PII guardrails disabled by default?

According to the [`featureFlagDefinitions.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/featureFlagDefinitions.ts) source configuration, both `PII_REDACTION_ENABLED` and `PII_RESPONSE_SANITIZATION` default to `false` to prevent accidental data transformation or loss. Operators must explicitly enable these features after evaluating their specific compliance requirements and testing impact on model outputs.

### Can I disable guardrails for specific users or API keys?

The current implementation supports per-request disabling via the `x-omniroute-disabled-guardrails` header, not per-user or per-key configuration. To implement user-scoped guardrail policies, you would extend the `resolveDisabledGuardrails()` logic in [`src/lib/guardrails/registry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/registry.ts) to check additional context such as authenticated user roles or API key metadata.

### What happens when multiple guardrails trigger on the same request?

The `registry.runAll(context)` method executes guardrails in strict priority order and **short-circuits** on the first blocking result. The request handler immediately returns the first violation's `reason` via `buildErrorBody()`, so downstream guardrails do not execute. This design prevents information leakage through partial guardrail execution.