How to Implement Custom Guardrails with PII Masking and Vision Bridging in OmniRoute
You can implement custom guardrails in OmniRoute by extending the GuardrailBase class in src/lib/guardrails/base.ts, registering your implementation in 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 defines the GuardrailBase abstract class that all guardrails must extend. Second, the central registry in 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 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, 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:
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:
// 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, while image validation and encoding utilities live in src/lib/guardrails/visionBridgeHelpers.ts. The router in src/lib/guardrails/visionBridgeRouter.ts determines applicability based on model capabilities and request content.
Request Format and Configuration
Enable the feature via environment variable:
VISION_BRIDGE_ENABLED=true
Clients submit requests with a vision_images array containing URLs or base64-encoded strings:
{
"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:
x-omniroute-disabled-guardrails: visionBridge
Creating a Custom Guardrail
Extend the Base Class
Create a new file in src/lib/guardrails/myCustomGuardrail.ts that inherits from GuardrailBase:
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:
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/:
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:
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.tsto manage pluggable request/response processors. - PII masking automatically redacts sensitive data when
PII_REDACTION_ENABLED=true, using regex patterns defined insrc/lib/guardrails/piiMasker.ts. - Vision bridging converts image URLs and base64 strings into multipart payloads for multimodal models, controlled by
VISION_BRIDGE_ENABLEDinsrc/lib/guardrails/visionBridge.ts. - Custom guardrails extend
GuardrailBasefromsrc/lib/guardrails/base.tsand implement theprocess(context)method to mutate requests or responses. - Use the
x-omniroute-disabled-guardrailsheader 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 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 to ensure your modifications apply before image processing occurs.
What image formats does the vision bridge support?
According to 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.
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 →