Guardrail Adapter Reference
This reference covers the binary’s CLI flags, environment variables, static configuration file schema, gRPC ext_proc surface, HTTP endpoints, provider interface, and MCP message types handled by the adapter.
Command-line flags
| Flag | Type | Default | Description |
|---|---|---|---|
|
string |
|
TCP address for the gRPC ext_proc server. Format: |
|
string |
|
TCP address for the HTTP health check server. |
|
string |
|
Maximum body size buffered per direction (request or response) in the inspection path. Human-readable units are accepted: |
Environment variables
| Variable | Default | Description |
|---|---|---|
|
(unset) |
Path to a static YAML configuration file. When set, the file is loaded and validated at startup; invalid files cause a non-zero exit. Dynamic metadata and |
|
|
Log verbosity. Accepted values (case-insensitive): |
|
|
Log output format. Accepted values (case-insensitive): |
Static configuration file
When GUARDRAIL_CONFIG_FILE is set, the adapter reads a YAML file with the following schema.
All fields are validated at startup; an unknown field or a missing required field causes a non-zero exit.
provider: presidio-api # required; currently only presidio-api is supported
modes: # required; non-empty list
- pre_call # inspect outgoing tool-call arguments
- post_call # inspect incoming tool-call results
presidio: # required when provider: presidio-api
endpoint: http://presidio-analyzer:3000 # required; base URL of the Presidio Analyzer service
language: en # optional; ISO language code; default: empty (Presidio default)
score_thresholds: # optional; maps entity type to minimum confidence (0.0–1.0)
ALL: "0.5" # "ALL" is the catch-all; per-entity keys override it
EMAIL_ADDRESS: "0.8"
entity_actions: # optional; maps entity type to action
EMAIL_ADDRESS: MASK # MASK: replace with <ENTITY_TYPE> placeholder
CREDIT_CARD: BLOCK # BLOCK: reject the whole request with HTTP 403
Modes
| Value | Behaviour |
|---|---|
|
Inspect outgoing request bodies (MCP |
|
Inspect incoming response bodies (MCP |
Entity actions (Presidio provider)
| Value | Behaviour |
|---|---|
|
Default when no action is configured. Entity is detected but no modification is made. |
|
Replace the detected entity span with a placeholder such as |
|
Reject the entire request or response with an HTTP 403 (request side) or 502 (response side). BLOCK takes precedence over MASK when both match the same entity. |
ext_proc gRPC surface
The adapter implements the envoy.service.ext_proc.v3.ExternalProcessor service defined in the Envoy control-plane API.
Service and port
| Item | Value |
|---|---|
gRPC service |
|
Default port |
|
TLS |
None (cleartext). Use a service mesh sidecar or Envoy’s transport-socket configuration for mTLS. |
gRPC health service |
|
gRPC reflection |
Enabled ( |
Implemented RPC
| Method | Description |
|---|---|
|
Bidirectional streaming RPC. Each |
ProcessingRequest types handled
| Type | Behaviour |
|---|---|
|
Resolves the per-stream guardrail configuration from static config, |
|
Buffers body chunks until end-of-stream when |
|
Checks the HTTP status code; non-2xx responses skip body inspection. Activates the frame-aware SSE path for |
|
Mirrors request-body behaviour for the response direction. Oversized bodies are rejected with HTTP 502. For |
|
Returns an empty |
|
Returns an empty |
Guardrail configuration resolution order
On each new stream, configuration is resolved from the first matching source:
-
Static file (
GUARDRAIL_CONFIG_FILE) — takes precedence when set; dynamic sources are ignored. -
MetadataContext.FilterMetadata— populated when Envoy forwards dynamic metadata. -
x-guardrail-*request headers — fallback injected by a Lua filter viaEnvoyPatchPolicy.
When no configuration is resolved, all traffic passes through unmodified.
HTTP endpoints
| Method | Path | Description |
|---|---|---|
|
|
Returns HTTP 200 with body |
Provider interface
A custom guardrail provider must implement the GuardrailProvider interface defined in internal/provider/provider.go:
type GuardrailProvider interface {
// ProcessRequest analyzes text extracted from a tool-call request.
// Returns the (possibly masked) text and optional metadata needed to
// process the corresponding response. Returns a non-nil error when the
// request must be blocked; the error message is forwarded to the caller
// as the block reason.
ProcessRequest(ctx context.Context, text string) (*Result, error)
// ProcessResponse restores processed text using metadata from ProcessRequest.
// For example, a masking provider uses this to deanonymize response content
// when the request-side metadata records the original spans.
ProcessResponse(ctx context.Context, processedText string, metadata interface{}) (string, error)
}
Result carries the processed text and optional provider-specific metadata:
type Result struct {
Text string // original or masked text
ResponseMetadata interface{} // passed back to ProcessResponse; nil if text was not modified
}
The built-in presidio package in internal/provider/presidio/ is the reference implementation.
To add a new provider, implement the interface and register the provider name in extproc.Server.createProvider.
MCP message types parsed
The MCP parser (internal/protocol/mcpparser/) recognises JSON-RPC 2.0 messages.
Only the following MCP method and response shape trigger inspection; all other methods and shapes pass through unmodified.
Request side (pre_call)
| Method | Extracted text fields |
|---|---|
|
All string values nested anywhere in |
All other methods (e.g. tools/list, initialize, notifications) return shouldInspect=false and pass through unchanged.
Response side (post_call)
| Shape | Extracted text fields |
|---|---|
JSON-RPC 2.0 success response whose |
The |
JSON-RPC error responses (result.error present) pass through unchanged.