# How to Implement Custom Guardrails with PII Masking and Vision Bridging in OmniRoute

> Learn to implement custom guardrails with PII masking and vision bridging in OmniRoute. Extend GuardrailBase, register your implementation, and control activation easily. Enhance your data protection today.

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

---

**You can implement custom guardrails in OmniRoute by extending the `GuardrailBase` class in [`src/lib/guardrails/base.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/base.ts), registering your implementation in [`src/lib/guardrails/registry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/registry.ts), and toggling activation via environment variables or the `x-omniroute-disabled-guardrails` header.**

OmniRoute provides a pluggable **guardrails framework** that intercepts request and response payloads to enforce security, compliance, and multimodal functionality policies. This guide demonstrates how to implement custom guardrails with PII masking and vision bridging by leveraging the core abstractions defined in the repository’s source code.

## Understanding the Guardrail Architecture

The guardrail system relies on three core components. First, the **base interface** in [`src/lib/guardrails/base.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/base.ts) defines the `GuardrailBase` abstract class that all guardrails must extend. Second, the **central registry** in [`src/lib/guardrails/registry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/registry.ts) maintains a `GuardrailRegistry` map that instantiates guardrails and tracks their default enable states. Third, the **execution entry point** in [`src/middleware/promptInjectionGuard.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/middleware/promptInjectionGuard.ts) invokes `applyGuardrails(request, response)` to process each HTTP request through the active guardrail pipeline.

Configuration flows through environment variables—such as `PII_REDACTION_ENABLED` and `VISION_BRIDGE_ENABLED`—and per-request opt-out headers. The registry reads these flags to determine which guardrails execute for each request.

## Enabling PII Masking for Data Redaction

### How the PII Masker Works

The built-in PII masker, implemented in [`src/lib/guardrails/piiMasker.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/piiMasker.ts), scans both incoming requests and outgoing responses for personal identifiers using regular expression patterns. Detected values—including emails, phone numbers, and credit card numbers—are replaced with the static placeholder `"[REDACTED]"`.

### Configuration and Activation

Set the environment variable to enable automatic redaction:

```dotenv
PII_REDACTION_ENABLED=true

```

When active, a request containing sensitive data undergoes transformation before reaching the upstream provider. For example, a payload containing `"My email is alice@example.com"` becomes `"My email is [REDACTED]"` in the payload forwarded to the model.

### Extending Detection Patterns

To add custom PII patterns, modify the `PII_REGEXES` array in [`src/lib/guardrails/piiMasker.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/piiMasker.ts):

```ts
// Example: Add Social Security Number detection
PII_REGEXES.push(/\b\d{3}-\d{2}-\d{4}\b/g);

```

After updating the patterns, redeploy the application to apply the new redaction rules.

## Implementing Vision Bridging for Multimodal Requests

### Architecture Overview

The **vision-bridge** guardrail enables multimodal support by transforming JSON requests containing image references into provider-specific multipart formats. The orchestration logic resides in [`src/lib/guardrails/visionBridge.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/visionBridge.ts), while image validation and encoding utilities live in [`src/lib/guardrails/visionBridgeHelpers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/visionBridgeHelpers.ts). The router in [`src/lib/guardrails/visionBridgeRouter.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/visionBridgeRouter.ts) determines applicability based on model capabilities and request content.

### Request Format and Configuration

Enable the feature via environment variable:

```dotenv
VISION_BRIDGE_ENABLED=true

```

Clients submit requests with a `vision_images` array containing URLs or base64-encoded strings:

```json
{
  "model": "gpt-4o-vision",
  "messages": [{"role": "user", "content": "Describe this image."}],
  "vision_images": [
    "https://example.com/photo.jpg",
    "data:image/png;base64,iVBORw0..."
  ]
}

```

The guardrail downloads remote images, validates MIME types (`image/jpeg`, `image/png`, `image/webp`), and rewrites the request into the multipart format expected by vision-capable models. The processed request attaches images under the `"file"` key while preserving the text prompt in the JSON part.

### Disabling for Specific Requests

To skip vision bridging for a particular call, include the opt-out header:

```http
x-omniroute-disabled-guardrails: visionBridge

```

## Creating a Custom Guardrail

### Extend the Base Class

Create a new file in [`src/lib/guardrails/myCustomGuardrail.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/myCustomGuardrail.ts) that inherits from `GuardrailBase`:

```ts
import { GuardrailBase, GuardrailContext } from "./base";

export class TimestampGuardrail extends GuardrailBase {
  static readonly ID = "timestampGuardrail";

  async process(context: GuardrailContext): Promise<void> {
    if (typeof context.request === "object" && context.request !== null) {
      (context.request as any).metadata = {
        ...(context.request as any).metadata,
        processed_at: new Date().toISOString()
      };
    }
  }
}

```

The `GuardrailContext` interface provides mutable access to the `request` and `response` objects. The `process` method executes asynchronously and may modify the context in place.

### Register the Implementation

Import and register the guardrail in [`src/lib/guardrails/registry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/registry.ts):

```ts
import { TimestampGuardrail } from "./myCustomGuardrail";

export const GuardrailRegistry = new Map<string, GuardrailEntry>([
  // ... existing entries
  [
    "timestampGuardrail",
    {
      guardrail: new TimestampGuardrail(),
      enabledByDefault: process.env.TIMESTAMP_GUARDRAIL_ENABLED === "true"
    }
  ]
]);

```

### Testing Your Implementation

Add unit tests under `tests/unit/guardrails/`:

```ts
import { TimestampGuardrail } from "../../../src/lib/guardrails/myCustomGuardrail";

test("injects timestamp metadata", async () => {
  const guard = new TimestampGuardrail();
  const ctx = { request: { foo: "bar" }, response: undefined };
  await guard.process(ctx);
  expect((ctx.request as any).metadata.processed_at).toMatch(
    /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/
  );
});

```

Run `npm run test:all` to verify that your guardrail integrates correctly with the existing pipeline.

## Controlling Guardrail Execution Per Request

Both built-in and custom guardrails respect the `x-omniroute-disabled-guardrails` header. To disable specific guardrails for a single request, include the header with a comma-separated list of IDs:

```http
x-omniroute-disabled-guardrails: piiMasker,visionBridge,timestampGuardrail

```

This bypasses the specified guardrails while allowing others to execute normally, providing fine-grained control over processing overhead and compliance requirements.

## Summary

- OmniRoute’s guardrail system uses a **registry pattern** centered in [`src/lib/guardrails/registry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/registry.ts) to manage pluggable request/response processors.
- **PII masking** automatically redacts sensitive data when `PII_REDACTION_ENABLED=true`, using regex patterns defined in [`src/lib/guardrails/piiMasker.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/piiMasker.ts).
- **Vision bridging** converts image URLs and base64 strings into multipart payloads for multimodal models, controlled by `VISION_BRIDGE_ENABLED` in [`src/lib/guardrails/visionBridge.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/visionBridge.ts).
- Custom guardrails extend `GuardrailBase` from [`src/lib/guardrails/base.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/base.ts) and implement the `process(context)` method to mutate requests or responses.
- Use the `x-omniroute-disabled-guardrails` header to selectively bypass guardrails for individual requests.

## Frequently Asked Questions

### How do I disable PII masking for a specific API call?

Send the header `x-omniroute-disabled-guardrails: piiMasker` with your request. This instructs the pipeline in [`src/middleware/promptInjectionGuard.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/middleware/promptInjectionGuard.ts) to skip the PII masker while processing other active guardrails.

### Can I modify the request body before it reaches the vision bridge?

Yes. Custom guardrails execute in the order they appear in the `GuardrailRegistry` map. Register your guardrail before the vision bridge entry in [`src/lib/guardrails/registry.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/registry.ts) to ensure your modifications apply before image processing occurs.

### What image formats does the vision bridge support?

According to [`src/lib/guardrails/visionBridgeHelpers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/lib/guardrails/visionBridgeHelpers.ts), the vision bridge validates and processes `image/jpeg`, `image/png`, and `image/webp` formats. Remote URLs are downloaded and validated before encoding into the provider-specific multipart structure.

### Is there a performance penalty for enabling multiple guardrails?

Each guardrail introduces minimal overhead as it processes the request/response objects in memory. The PII masker uses compiled regular expressions, while the vision bridge performs network I/O only when fetching remote images. Profile your specific workload if processing latency becomes a concern.