OmniRoute Security Measures: Prompt Injection Guard and PII Redaction Explained
OmniRoute implements layered security guardrails including a prompt injection guard with regex-based detection and configurable severity scoring, plus bidirectional PII redaction for both requests and LLM responses, all controlled by runtime feature flags.
OmniRoute (diegosouzapw/OmniRoute) protects AI interactions through a defense-in-depth architecture that scans inbound prompts for malicious instructions and sanitizes sensitive data on both sides of the LLM call. The security system is built around modular guardrails that operators can enable, disable, or tune without code changes. This article examines the implementation details of the prompt injection guard and PII redaction features based on the actual source code.
Prompt Injection Guard Architecture
The prompt injection guard operates as middleware that intercepts requests before they reach the LLM provider.
Core Components
Three files collaborate to provide injection protection:
src/middleware/promptInjectionGuard.ts— HTTP middleware wrappersrc/lib/guardrails/promptInjection.ts— guardrail class and scoring logicsrc/shared/utils/inputSanitizer.ts— shared scanning utilities
How the Guard Evaluates Requests
- Body parsing: The middleware (
createInjectionGuard) parses the request and extracts message content - Pattern matching:
evaluatePromptInjectionruns built-in regexes (system_override_inline,system_prompt_leak) plus any custom patterns - Severity scoring: Detections are scored as
low/medium/highusing utilities fromsrc/shared/utils/injectionSeverity.ts - Action determination: Based on
INJECTION_GUARD_MODE(warn,block, orlog) and the block threshold, the request is logged, flagged, or rejected with HTTP 400
The scan is performance-bounded: only the first 16 KiB (MAX_INJECTION_SCAN_BYTES) of the concatenated prompt is examined to keep the hot path fast.
Middleware Integration Example
// src/app/api/v1/chat/completions/route.ts
import { withInjectionGuard } from "@/middleware/promptInjectionGuard";
import { handleChatCore } from "@/open-sse/handlers/chatCore";
export const POST = withInjectionGuard(async (request, _, parsedBody) => {
const payload = parsedBody ?? await request.json();
return handleChatCore(payload);
});
When blocking occurs, the middleware returns:
{
"type": "injection_detected",
"code": "SECURITY_001",
"message": "Prompt injection patterns detected"
}
HTTP headers X-Injection-Flagged and X-Injection-Detections are always added for downstream observability.
Custom Pattern Support
Operators can extend detection at runtime without modifying core code:
import { PromptInjectionGuardrail } from "@/lib/guardrails/promptInjection";
const guard = new PromptInjectionGuardrail({
customPatterns: [
{
name: "proprietary_token_leak",
pattern: /sk-[a-zA-Z0-9]{32,}/i,
severity: "high"
},
],
});
await guard.preCall(requestBody, { log: console });
Custom patterns merge with DEFAULT_GUARD_PATTERNS and receive identical severity scoring.
PII Redaction System
OmniRoute provides bidirectional PII protection: sanitizing user inputs before they reach the LLM, and scrubbing LLM outputs before they reach users.
Request-Side PII Masking
Implementation: src/lib/guardrails/piiMasker.ts and processPII in src/shared/utils/inputSanitizer.ts
The request-side mask checks the feature flag PII_REDACTION_ENABLED (read from database → environment → default). When enabled, every string field in the payload is scanned against PII_PATTERNS and replaced with typed placeholders.
| Pattern | Placeholder | Validation |
|---|---|---|
[EMAIL_REDACTED] |
RFC 5322 regex | |
| Credit card | [CC_REDACTED] |
Luhn checksum via isValidLuhn() |
| CPF (Brazilian) | [CPF_REDACTED] |
Modulo 11 algorithm |
| CNPJ (Brazilian) | [CNPJ_REDACTED] |
Weighted digit validation |
| SSN | [SSN_REDACTED] |
Format XXX-XX-XXXX |
| IPv4/IPv6 | [IP_REDACTED] |
Standard patterns |
| Phone numbers | [PHONE_REDACTED] |
E.164 variants |
| AWS keys | [AWS_KEY_REDACTED] |
AKIA/ASIA prefixes |
| Generic API keys | [API_KEY_REDACTED] |
Heuristic patterns |
The mask returns detection counts for audit logging.
Response-Side PII Sanitization
Implementation: src/lib/piiSanitizer.ts
The response sanitizer is invoked by the post-call step of PIIMaskerGuardrail. It walks JSON responses recursively, applying the same regex set with four operating modes controlled by PII_RESPONSE_SANITIZATION_MODE:
redact— Replace matches with placeholders (default)warn— Log detections without modificationblock— Abort request with erroroff— Disable processing
Streaming Response Handling
For streaming responses, sanitizePIIChunk handles partial buffers safely. A match ending at a chunk boundary is deferred until the next chunk arrives (endMatchIndex handling) to prevent premature redaction of incomplete tokens.
Manual PII Sanitization
import { sanitizePII } from "@/lib/piiSanitizer";
const raw = "Contact: john.doe@company.com, Card: 4532-0151-1283-0356";
const { text, detections, redacted } = sanitizePII(raw);
console.log(text);
// "Contact: [EMAIL_REDACTED], Card: [CC_REDACTED]"
console.log(detections);
// [
// { pattern: "email", count: 1, severity: "medium" },
// { pattern: "credit_card", count: 1, severity: "high" }
// ]
Feature Flag Control System
All security guards are runtime-configurable through src/shared/utils/featureFlags.ts. The resolution order is:
- Database table
feature_flags(highest priority) - Environment variables
- Hardcoded defaults
Key Environment Variables
# Request-side controls
PII_REDACTION_ENABLED=true
INPUT_SANITIZER_ENABLED=true
# Injection guard
INJECTION_GUARD_MODE=block # warn | block | log
# Response-side controls
PII_RESPONSE_SANITIZATION=true
PII_RESPONSE_SANITIZATION_MODE=redact # redact | warn | block | off
This design allows security posture changes without deployment, supporting gradual rollouts and incident response.
Audit Logging and Observability
Both guardrails integrate with GuardrailContext.log:
| Severity | Event Type | Log Level |
|---|---|---|
| High-confidence injection | Blocked request | warn |
| Medium confidence injection | Flagged request | info |
| PII detection (redact mode) | Sanitization applied | debug |
| PII detection (block mode) | Aborted response | warn |
Log metadata includes pattern names, severity scores, detection counts, and request correlation IDs.
Configuration Best Practices
For production deployments of OmniRoute, consider this security layering:
- Enable request-side PII redaction (
PII_REDACTION_ENABLED=true) to prevent user data leakage to LLM providers - Set injection guard to
blockmode for high-risk endpoints; usewarnmode during initial rollout to assess false positive rates - Enable response-side sanitization when LLMs may echo training data or generate realistic-looking fake credentials
- Customize patterns for domain-specific secrets (internal API prefixes, proprietary formats) via the
customPatternsAPI
Summary
- Prompt injection guard: Regex-based detection with severity scoring, configurable modes (
warn/block/log), 16 KiB scan limit, and custom pattern support viasrc/lib/guardrails/promptInjection.ts - PII redaction: Bidirectional sanitization with checksum-validated patterns (Luhn for cards, modulo 11 for Brazilian IDs), streaming-safe chunk processing, and typed placeholders
- Runtime control: Database-backed feature flags with environment fallbacks for zero-code security adjustments
- Observability: Structured logging with HTTP headers for downstream telemetry
Frequently Asked Questions
How does OmniRoute's prompt injection guard differ from simple input validation?
The guard uses multi-pattern regex matching with severity scoring rather than binary allow/block lists. It evaluates detections against configurable thresholds (shouldBlockDetections), supports custom patterns at runtime, and provides graduated responses (log/warn/block) based on INJECTION_GUARD_MODE. The 16 KiB scan limit ensures low latency even on large prompts.
Can PII redaction handle streaming responses without corrupting JSON?
Yes. The sanitizePIIChunk function in src/lib/piiSanitizer.ts tracks endMatchIndex to defer redaction of partial matches at chunk boundaries. This prevents false replacements when a sensitive token spans multiple chunks, maintaining valid JSON structure throughout the stream.
What happens if both injection detection and PII redaction trigger on the same request?
Processing occurs in sequence: PII redaction runs first on the request body (if enabled), then the sanitized content is evaluated for prompt injection. If injection is detected and mode is block, the request fails with SECURITY_001 before reaching the LLM. Both detections are logged independently with their respective pattern metadata.
Is checksum validation applied to all PII patterns?
No. Luhn validation (isValidLuhn) and Brazilian ID algorithms apply only to credit cards, CPF, and CNPJ where mathematical verification reduces false positives. Other patterns (email, IP, phone) rely on regex matching alone. The pattern definitions in PII_PATTERNS specify which validators to invoke.
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 →