Guardrails run inline on every request and response, deterministic, pure-Rust, and microseconds on the hot path. Always-on masking redacts PII and leaked secrets; declarative checks add deny/observe policy; ML / external checks run off-path via a webhook. A blocked request returns 446 with code routeplane_guardrails_denied, and the per-check results are attached under x_routeplane.check_results. Outcomes carry the matched category, never the matched text.
| Check | What it catches |
|---|---|
| PII redaction (always-on) | email, phone, SSN, credit card (Luhn), IPv4, India PAN & Aadhaar (Verhoeff) → masked on ingress + egress. |
detect_secrets | API/provider keys (sk-…), AWS/GitHub/Slack/Stripe/Google keys, JWTs, PEM private keys. |
prompt_injection | jailbreak / injection / exfiltration signatures (Aho-Corasick, linear-time). |
detect_pii | PII-presence policy check (deny/observe), separate from masking. |
banned_keywords | topic / competitor / keyword denylists. |
regex, counts, json_schema, valid_urls, webhook | declarative format/policy checks; webhook is the off-path hook for ML/external guardrails (tenant-config only). |
Detectors are linear-time by construction (no catastrophic backtracking), and their precision/recall is gated against a labelled corpus on every PR. See the endpoints for the MCP agent-gateway authorization surface.
{
"error": {
"message": "Request blocked by Routeplane guardrails",
"type": "invalid_request_error",
"code": "routeplane_guardrails_denied"
},
"x_routeplane": { "check_results": [ { "check": "prompt_injection", "passed": false } ] }
}
How-to: Add a guardrail → define before/after-request checks on a key, step by step.