Overview
Guardrails are a pipeline of rules that run before a request reaches any LLM provider. They can inspect, modify, or reject requests — giving you centralized control over every prompt that flows through GoModel. Guardrails work across all text-based endpoints:/v1/chat/completions/v1/responses/v1/messages
Guardrails for images, TTS, STT, and video models are planned as a separate
system and are not covered here.
Quick Start
Add aguardrails section to your config/config.yaml:
How It Works
- Messages are extracted from the incoming request into a normalized format
- The guardrails pipeline processes the messages (inject, modify, or reject)
- Modified messages are applied back to the original request
- The request continues to the LLM provider
/chat/completions, /responses, and /messages.
Execution Order
Each guardrail has anorder value that controls when it runs:
- Same order → run in parallel (concurrently)
- Different order → run sequentially (ascending)
Configuration
Full Structure
Environment Variable
You can toggle guardrails without editing the config file:Rule Fields
Guardrail Types
system_prompt
Adds, replaces, or decorates the system prompt on every request.
Settings
Modes
- inject
- override
- decorator
Adds a system message only if none exists. Existing system prompts are left untouched.Behavior:
- Request has no system prompt → adds one
- Request already has a system prompt → no change
llm_based_altering
Rewrites selected message roles by calling an auxiliary model before the main
provider request runs. This is useful for PII anonymization and other
prompt-preserving rewrites.
The default prompt is derived from LiteLLM’s data_anonymization guardrail,
so a minimal config acts as an anonymizing preprocessor.
Settings
When
llm_based_altering calls the auxiliary model, GoModel runs that call
through the normal translated request path in-process. That means ordinary
workflow selection, failover, usage, audit, and cache behavior still apply.
The internal request uses:
- path:
/v1/chat/completions - user path:
{guardrail.user_path or caller user path}/guardrails/{guardrail name} - request origin:
guardrail
Example
header_modification
Conditionally sets or removes outbound provider-request headers based on
the inbound request headers. Use it to correct or steer the behavior of
existing clients and agents without changing them — for example pinning an
Anthropic-Beta feature flag for one coding agent, stripping internal debug
headers before they leave the gateway, or renaming a header a client sends
into the one a provider expects.
Unlike the message-based types, this guardrail never touches the request body.
It runs right after workflow resolution, and its changes are applied when the
outbound provider request is built — on translated routes, passthrough routes
(/p/{provider}/...), and realtime websocket upgrades alike.
Settings
Each
when condition names a header and one predicate: matches (RE2
regex), equals (exact string), or present: true/false (existence check —
the default when no predicate is given). An explicit equals: "" matches a
header whose value is empty.
Each action has an action (set or remove) and a header. A set takes
either a literal value or from_header, which copies the first inbound
value of another header (the action is skipped when that header is absent).
Credential headers (
Authorization, Cookie, X-Api-Key, …) and
transport headers (Host, Content-Length, Connection, …) are rejected
as condition sources and action targets at authoring time. Payload metadata
headers (Accept-Encoding, Content-Encoding, and Content-Type) are also
reserved because changing them can break decompression or body parsing. The
runtime refuses to touch all of these as a second line of defense.Observability
Every header rule that changes a request is recorded on the audit entry’s request-revision chain — the same mechanism used for body rewriters. Only the delta is stored. WhenLOGGING_LOG_HEADERS=true, set headers include their
final values after normal credential redaction; otherwise only set header names
are stored. Removed headers always contain names only. A request with no
matching rules records nothing. Revisions describe the intended change and are
not proof that execution reached provider egress. The dashboard request log
shows each change as a Rewritten tab on the entry’s detail drawer.