Skip to main content

Overview

AgentGateway can call Fiddler’s guardrail webhook adapter before and after every LLM call, redacting PII and secrets at the proxy layer. This is a separate integration from AgentGateway tracing — guardrails run inline on the request path (they can block or rewrite the call), while tracing exports spans out-of-band for observability. You can use either independently or both together.
Guardrails on Fiddler’s canonical, versioned endpoints require AgentGateway ≥ v1.4.0 — the first release containing Fiddler’s upstream OSS contribution that lets the webhook’s headers CEL config route calls to a path other than the hardcoded /request / /response. See Prerequisites for the earlier-version workaround.
Fiddler checks for:
  • PII — personal identifiable information (names, emails, phone numbers, SSNs, credit cards, etc.)
  • Secrets — API keys, tokens, credentials, and connection strings
AgentGateway’s webhook protocol supports masking: detected PII and secrets are redacted in place and the (sanitized) request still reaches the model, rather than being blocked outright.

How It Works

Each gateway speaks its own wire format — AgentGateway, Kong, and LiteLLM each wrap the prompt/response in a different envelope and expect a differently shaped answer back. Fiddler exposes a dedicated adapter per gateway (under /v3/guardrails/agentgateway/*, /v3/guardrails/kong, and /v3/guardrails/litellm/* respectively — see each page’s own Endpoints/API Reference section for the exact paths) so each protocol is translated to and from Fiddler’s guardrail checks without the gateways needing to agree on a shared format. AgentGateway wraps each request/response in its own envelope format and expects one of three actions back:

Prerequisites

  • AgentGateway ≥ v1.4.0 — earlier versions cannot route webhook calls to a path other than the hardcoded /request / /response on the target host. Fiddler worked with the AgentGateway maintainers on this (agentgateway/agentgateway#2368, fixed in agentgateway/agentgateway#2595); on 1.4.0+ the webhook’s headers CEL config can set :path to call Fiddler’s canonical, versioned endpoints directly.
  • A named backend entry pointing at your Fiddler instance, referenced from the LLM model’s guardrails block.

Step 1: Configure AgentGateway

Add a named backend for the Fiddler guardrail webhook, then reference it from each model’s guardrails block:
A named backend: reference (rather than an inline host: on the webhook target) is required to attach backendAuth/backendTLS policies to the guardrail call. On standalone (non-Kubernetes) AgentGateway deployments, backend names with no namespace are stored with a leading slash — reference them as /fiddler-guardrail, not fiddler-guardrail (see agentgateway/agentgateway#2220).
The headers CEL config for setting :path requires AgentGateway ≥ v1.4.0. On earlier versions, omit the headers block — the webhook falls back to calling /request and /response at the backend’s root, which requires either a dedicated host/ingress rule for those exact paths or a rewrite rule in front of Fiddler.

Step 2: Start AgentGateway

Step 3: Verify

With no gateways block, AgentGateway’s llm.models config implies a default gateway serving LLM traffic on port 4000. Send a request with a known, dummy secret (correctly formatted, but not a real credential):
The secret is redacted before the request reaches the model — the completion is returned normally, with the model having only seen the sanitized prompt.

What Gets Scanned

  • Free-text messages — every message’s content field. PII/secrets are redacted in place (e.g. [REDACTED EMAIL_ADDRESS]) and the sanitized message array is returned to AgentGateway.
AgentGateway’s webhook protocol sends a simplified message shape — {role, content} only, no tool_calls, name, or other OpenAI chat-completions fields. AgentGateway strips these before calling the webhook, so there is nothing beyond message text for Fiddler to scan or redact on this integration.

Check Behavior

Checks are configured server-side via the same environment variables and thresholds used across all Fiddler guardrail integrations — see Guardrails for the underlying PII model, and the secrets detection tutorial for secrets. Since AgentGateway’s wire body carries no per-request config field, those defaults can be overridden per route via static HTTP headers in the webhook’s headers CEL config — the same mechanism used for the :path override in Step 1. This gives AgentGateway access to the same set of checks and overrides as the LiteLLM integration’s additional_provider_specific_params, but applied per route rather than per individual request — see Header-Based Configuration.

PII and Secrets

Header-Based Configuration

Each header value must be a CEL string literal — note the nested quotes ('"pii,secrets"'), matching the :path override above. A bare, unquoted value (e.g. "x-fiddler-pii-mode": "block") is parsed as an unresolvable CEL field reference; AgentGateway drops that header instead of raising an error, so the corresponding override is silently ignored.
A header naming a check that isn’t pii or secrets (for example, a typo) is dropped with a server-side warning, not treated as valid — but this only falls back to running every check when none of the requested names are recognized. A partial typo, like pii,screts, still recognizes pii and runs only that check — secrets is silently skipped, with no signal visible outside the server logs. Per-check override headers (x-fiddler-pii-mode, etc.) only take effect when the corresponding check is present in x-fiddler-guardrails; if x-fiddler-guardrails itself is absent, override headers are never read at all, so every check runs with system defaults regardless of what other x-fiddler-* headers are set.
x-fiddler-timeout sets Fiddler’s own check budget, not AgentGateway’s webhook call timeout — see Failure Mode. Since AgentGateway’s hardcoded webhook timeout (10s) is shorter than Fiddler’s default check budget (12s), raising x-fiddler-timeout above 10s has no effect unless the check also completes within AgentGateway’s own window.

Action Mapping

AgentGateway’s webhook protocol uses serde untagged deserialization on the response body — there is no explicit "type" discriminator field. The three action shapes are distinguished by their JSON structure:
mask and reject are disambiguated by the type of body: an object ({"messages": [...]} or {"choices": [...]}) means mask, a string means reject.

Failure Mode

The webhook has a fixed 10-second wall-clock timeout, hardcoded by AgentGateway itself (with_default_timeout in crates/agentgateway/src/llm/policy/mod.rs) — there is currently no config field to override it. If your guardrail backend is slower than this (for example, a cold-starting GPU inference worker), requests will time out before the check completes. AgentGateway’s webhook policy defaults to failClosed: if the webhook is unreachable or returns an error (including a timeout), the request is rejected rather than allowed through unscanned. Set failureMode: failOpen on the webhook config to allow requests through instead when the guardrail is unavailable — weigh this against your security posture, since fail-open means unscanned content can reach the model during an outage.

Known Limitations

Endpoints

Authentication: Authorization: Bearer <your-fiddler-api-key> (set via backendAuth.key on the AgentGateway backend — AgentGateway injects the Bearer scheme itself, so configure the raw token value, not Bearer <token>).

Request Body

/request — the pre-LLM prompt guard:
/response — the post-LLM response guard:
Only content fields are scanned. AgentGateway’s simplified webhook message shape has no other fields to accept.

Response Body

See Action Mapping above for the full shape of each variant. Summarized: Fiddler’s adapter always returns HTTP 200 to AgentGateway — the status_code field inside a reject action tells AgentGateway what to return to the client (default 403).