Guardrails
Content safety pipeline with built-in scanners and external providers.
Overview
BrainstormRouter's guardrail pipeline scans every request for harmful content, PII, jailbreak attempts, and policy violations. Configure it to block (reject), warn (pass with headers), or log (record silently).
In addition to content guardrails, the Guardian middleware (src/api/middleware/guardian.ts) provides consumption protection: pre-request cost prediction, post-response efficiency scoring, EWMA-based output estimation, and per-tenant privacy modes — all within a < 5ms p95 latency budget.
Built-in scanners
Three scanners ship out of the box:
| Scanner | Detection | Default |
|---|---|---|
builtin | Regex-based jailbreak and harmful content patterns | Enabled |
pii | Email, phone, SSN, credit card, IP address, API keys | Enabled |
topic-restriction | Keyword/pattern-based topic deny/allowlists | Disabled |
Configuration
Set your guardrail pipeline per-tenant:
await client.guardrails.updateConfig({
enabled: true,
mode: "block",
confidenceThreshold: 0.7,
providers: [
{ id: "builtin", enabled: true },
{ id: "pii", enabled: true },
{ id: "topic-restriction", enabled: true },
],
});
curl
curl -X PUT https://api.brainstormrouter.com/v1/guardrails/config \
-H "Authorization: Bearer br_live_..." \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"mode": "block",
"providers": [
{"id": "builtin", "enabled": true},
{"id": "pii", "enabled": true}
]
}'
Modes
| Mode | Behavior |
|---|---|
block | Reject the request with a 400 error |
warn | Pass the request, add X-BR-Guardrail-Warning header |
log | Pass silently, record match in observability stream |
External providers
Register third-party guardrail services (Lakera, Pangea, custom HTTP):
await client.guardrails.registerProvider({
id: "lakera",
name: "Lakera Guard",
endpoint: "https://api.lakera.ai/v1/guard",
api_key: "lk_...",
template: "lakera", // uses built-in Lakera template
});
Templates provide pre-configured body formats, auth headers, and response mappings for popular providers. Custom providers can specify their own result_mapping.
Testing
Test your pipeline with sample text before going live:
const result = await client.guardrails.test("My SSN is 123-45-6789");
console.log(result.result.safe); // false
console.log(result.result.matches); // [{type: "pii", subtype: "ssn", ...}]
console.log(result.result.durationMs); // 2
Per-request bypass
Bypass guardrails for a single request by setting X-BR-Guardian: off or configuring guardianOff: true in the SDK constructor.
Streaming output guardrails
Inbound scanning catches dangerous inputs. Outbound streaming guardrails catch dangerous outputs — token-by-token, before they reach the client.
The StreamingGuardrailEvaluator (src/security/streaming-guardrails.ts) buffers tokens in a sliding window (default: 20 tokens) and evaluates them against:
- Governance rules — tenant-specific keyword enforcement (
<1ms, deterministic) - Blocked content patterns — regex matching on buffer + accumulated text
- PII scanning — email, phone, SSN, credit card, IP address
| Action | Behavior |
|---|---|
allow | Forward tokens to client |
truncate | Sever the stream — all future tokens return "" |
redact | Replace PII inline: [REDACTED:email], [REDACTED:ssn] |
replace | Substitute governance violation message + sever |
Every action records a StreamGuardrailVerdict with guardrail ID, action, reason, match count, and character offset — available for audit and SIEM export.
See Streaming Security: Code vs Reality for the full pipeline with code examples.
PII air gap
When piiMode is "airgap", PII is stripped before data leaves the system and rehydrated on return (src/security/pii-airgap.ts):
// Outbound: PII replaced with reversible tokens
const { scrubbed, tokens } = await scrubAndTokenize(text, scanner);
// "Contact john@acme.com" → "Contact [PII:email:a1b2c3d4]"
// Inbound: tokens restored from in-memory map
const restored = rehydrate(externalResult, tokens);
The token map is held in memory — PII values never leave the process boundary.
Egress allowlist
Restrict which external domains your services can reach (src/security/egress-allowlist.ts):
checkEgressDomain("https://api.openai.com/v1/completions", [
"api.openai.com",
"api.anthropic.com",
"*.googleapis.com", // wildcard subdomain support
]);
// → { allowed: true }
When an egress check fails, the request is blocked with the reason logged. Empty allowlist = unrestricted (opt-in enforcement).
SIEM export
Guardrail events export to your SIEM in two formats (src/security/siem-export.ts):
| Format | Targets | Function |
|---|---|---|
| CEF | Splunk, ArcSight, QRadar | toCef() |
| ECS JSON | Elastic, Datadog, custom | toSiemJson() |
Both formats include severity mapping (debug=0 through critical=10), event categorization (authentication, configuration, network, process), and batch export with configurable minimum severity filtering.
Observability
Guardrail matches are broadcast to your configured observability destinations as guardrail events.