Guardrails guide
How to configure LLM and MCP request/response guardrails.
Overview
Guardrails inspect traffic before it leaves Cortega or before it is returned to the caller.
Use guardrails to:
- mask PII or secrets
- block unsafe prompts or responses
- call moderation or safety providers
- enforce different policies for models, keys, MCP servers, or MCP tools
Guardrail types
| UI type | What it does |
|---|---|
| Regex | Built-in detectors (SSN, credit card, phone, email, CA SIN) plus your own patterns; masks or blocks on a match. No external call. |
| Presidio | Microsoft Presidio entity detection and anonymization, run by Cortega's Presidio service. Supports custom recognizers and the Log persistence scope (see below). |
| Webhook | Calls your own HTTP endpoint implementing Cortega's guardrail webhook contract. |
| OpenAI moderation | Calls the OpenAI moderations API. |
| Local model | Calls a locally hosted classifier model; no upstream credential. |
| Azure AI Content Safety | Calls Azure AI Content Safety. |
| Google Model Armor | Calls Google Model Armor. |
| Bedrock Guardrails | Applies an AWS Bedrock guardrail. |
The model-backed types (OpenAI moderation, Azure AI Content Safety, Google Model Armor, Bedrock Guardrails) need a credential or an endpoint/region. See Provider credentials.
Create a guardrail
Navigate to Guardrails. Use Guided setup for a walkthrough that also proposes a starter set of guardrails, or New Guardrail to add one directly:
- Click New Guardrail.
- Enter a name.
- Choose phase: request or response.
- Choose the guardrail type (see the table above).
- Choose execution type.
- Configure type-specific settings, and a credential for the model-backed types.
- Choose scope.
- Save as draft or activate it.
Draft guardrails do not enforce. Active guardrails enforce after the gateway receives updated config.
Provider credentials
The model-backed guardrail types call an external service. The Guided setup wizard has a credentials step that collects what each type you keep needs:
- OpenAI moderation: choose Reuse OpenAI provider (Cortega uses the stored, encrypted credential from an existing Models → Providers OpenAI entry) or Use environment variable (Cortega reads a named env var, pre-filled with the conventional name). Reuse avoids keeping a second copy of the key.
- Azure AI Content Safety: the resource endpoint.
- Bedrock Guardrails: the guardrail ID, region, and version (
DRAFTor a published number). Cortega signs with its ambient AWS credentials. - Google Model Armor: the project and location.
Cortega never returns a stored credential in an API response. A guardrail whose credential can't be resolved does not enforce.
Execution types
Guardrails run in this order:
1. Sanitize
2. Parallel checks start
3. Ordered checks run while parallel checks are still running
4. Cortega allows only after ordered checks pass and the parallel expression passes
| UI term | Stored type | Use when |
|---|---|---|
| Sanitize | sanitize | The guardrail may mask or transform content |
| Parallel checks | async | The guardrail only passes or blocks and can run concurrently |
| Ordered checks | sync | The guardrail must run in a specific order after sanitation |
Sanitize and ordered checks run in the order shown in their tables. Parallel checks run concurrently.
Async pass logic
Parallel checks use AND and OR join behavior.
ANDchecks must all pass unless anORcheck passes.- An
ORcheck can allow the parallel expression when it passes. - If the expression is conclusively blocked, Cortega blocks the request/response.
Use AND for mandatory checks. Use OR for alternative safety checks
where any passing check is acceptable.
Scopes
Choose the narrowest scope that matches your intent.
| Scope | Applies to |
|---|---|
| All Models | LLM traffic for all models |
| Model | A specific direct LLM model (provider:model_id in the dropdown) or a managed team router (cortega-team-…) |
| Key | A specific LLM key identity |
| Log persistence | Presidio only. Redacts PHI in stored gateway telemetry (LLM/MCP query fields and Guardrail Log content attributes) before ClickHouse |
| MCP Server | Eligible MCP traffic for a server |
| Tool | Eligible MCP traffic for a tool |
Model scope matches the model name Cortega stamps after any team-router rewrite. For a team with Model Authorization configured, choose that team's router name in the Model dropdown so the guardrail covers the team's traffic. Direct models still cover unrouted calls that name that model. Hand-authored virtual models are not listed as Model choices; use All Models or Key for that traffic.
Request/response Model (or All Models) scope controls what the provider sees. Log persistence is a separate binding: without it, Guardrail Log and traffic rows can still store the pre-mask text even when the wire mask worked. Add Log persistence on a Presidio guardrail when observability must not retain cleartext PHI.
MCP guardrail coverage
MCP guardrails scan only methods that carry useful request/response content:
tools/callresources/readprompts/listprompts/getroots/listresources/templates/list
Other MCP protocol calls, such as initialize and notifications, are
logged in MCP Queries but are not content-scanned by guardrails.
Presidio custom patterns
When you create or edit a Presidio guardrail, use Custom detection patterns to teach Presidio identifiers its built-in detectors miss, for example an internal patient number or a local licence format.
Each pattern needs:
| Field | Purpose |
|---|---|
| Name | Recognizer name stored on the guardrail |
| Entity type | Entity the match is reported as (for example LOCATION or PERSON) |
| Regex | Detection pattern |
| Score | Confidence for the match (typically 0.85) |
| Context words | Optional nearby words that raise confidence |
Saving the guardrail sends these as presidio_ad_hoc_recognizers.
Clearing every custom pattern removes them from the guardrail.
When LOCATION is enabled, Cortega also applies built-in defaults for
US street lines and state/ZIP fragments. Those defaults do not appear in
the form; add custom patterns only for formats they do not cover. When
MEDICAL_LICENSE is enabled, a US state-prefixed medical licence default
is applied the same way.
Runtime logs
Use Observability → Guardrail Log to see what guardrails did.
Important fields:
| Field | Meaning |
|---|---|
| Runtime scope | LLM Request, LLM Response, MCP Request, or MCP Response |
| Input text | Text inspected on request paths |
| Output text | Text inspected on response paths |
| Guardrail | Guardrail name |
| Type | Guardrail provider/type |
| Score / threshold | Provider score compared to configured threshold |
| Action | Pass, mask, block, or below threshold |
| Latency | Time spent in that guardrail evaluation |
LLM Queries and MCP Queries show applied guardrails in their security area when the traffic row can be correlated with guardrail execution rows.
Troubleshooting
| Symptom | Likely cause | What to check |
|---|---|---|
| Guardrail does not fire | It is draft, disabled, wrong phase, or wrong scope | Check status, phase, and scope |
| Model-scoped guardrail misses a routed team | Scope is bound to a direct model, but the team router rewrote the request | Bind Model scope to that team's cortega-team-… router (or use All Models / Key) |
| Model scope does not apply to a hand-authored virtual model | Hand-authored virtual models are not Model-scope choices | Use All Models or Key |
| MCP request is not scanned | MCP method is outside the eligible method list | Check method in MCP Queries |
| MCP Guardrail Log row exists but MCP Query security is empty | MCP request correlation is not available yet | Use Guardrail Log directly |
| Output text appears without input text | Response guardrail row | Runtime scope should say LLM Response or MCP Response |
| Input text appears without output text | Request guardrail row | Runtime scope should say LLM Request or MCP Request |