Skip to main content
The TrustGuard policy sends what passes through the gateway to TrustGuard and applies the verdict it returns: allow, report, block, or a masked rewrite of the content itself. It covers LLM and MCP — the Model Context Protocol your agents call tools over — and it sends the whole conversation: the system prompt, every message with its role, the tool calls the assistant proposed, the tool definitions the client declared, and file and image attachments. What it detects is not configured here. The gateway policy decides which traffic is inspected and whether the gateway acts; the TrustGuard policy bound to the collector decides which detectors run and what a finding costs.
This policy puts a synchronous call in front of every inspected leg. With Direction set to both legs, a non-streaming turn makes two calls. How much that costs depends on your deployment and the size of the conversation, so measure it in your own environment rather than assuming. Enable the request leg first, measure, and only then add the response leg.

Before you configure: the runtime collector

A runtime collector bound to this gateway is a hard prerequisite, not a convenience. It is what authenticates the gateway to TrustGuard and what selects the TrustGuard policy that will judge the traffic.
The policy does not create the collector for you. Saving a TrustGuard policy with no collector bound fails. When this gateway has no runtime collector at all, the form says so before you get that far: No runtime collector is connected to this gateway yet. Create one so the TrustGuard policy can analyze this gateway’s traffic. Create one first — under Agent Security → Collectors, or inline from the policy form, which offers Create collector without leaving the panel.
The collector type is the TrustGate one, and it is native: there is no customer API key to paste, because the gateway authenticates through the platform. See Collectors for what a collector owns.

Configure the policy

Open Policies → Library → TrustGuard.

Runtime collector

Two cascading selects, and this pair is the whole binding: If the list is empty you get No collectors for this instance on this gateway and a Create collector link that makes one without leaving the panel.

Direction

Direction is the only control over what is inspected, and it defaults to Request & Response.

When TrustGuard cannot answer

What happens when the gateway cannot get a verdict depends on the cause.
  • The service is unavailable: fail open. A network error, an error from TrustGuard itself, rate limiting from the provider, a credential TrustGuard refuses, a gateway with no TrustGuard URL or credentials, unavailable entitlements, a call that does not answer in time, or a policy configuration the gateway cannot parse. The traffic is forwarded uninspected and the policy is recorded as Failed Open, with the reason. The caller sees nothing.
  • The content caused it: blocked in Enforce. A request or response body the gateway cannot read, content larger than TrustGuard accepts, or a mask the gateway cannot write back over sensitive data TrustGuard found. In Enforce the call is refused with 403 and recorded as Failed Closed (or Blocked, marked degraded with the reason, for a mask that cannot be applied).
  • Observe only records either case and never blocks.
Failing open keeps your application working through a TrustGuard outage, at the cost of a window in which nothing is being inspected and nothing in front of the caller says so. Watch for failed_open in Activity and on the failure count. Content over the limit is blocked in Enforce. A failure never relaxes a TrustGuard block or a 429 rate limit. Those are TrustGuard’s answers rather than failures, and they still refuse the request. See Modes and failures.

Mode and scope

Start in Observe, which records every verdict without acting on it, and switch to Enforce once the decisions look right. Read Modes and failures first: Observe here is narrower than it sounds. Scope works as it does for every policy — Requests from for applications and groups, Resources for MCP servers and tools. See Policies overview.

What is sent on each leg

Image and file attachments are collected on the request leg only, and their data goes with the rest of the conversation. A request carrying nothing but an attachment is still inspected. Three things are genuinely never seen: audio is never collected, on either leg; attachments on the response leg are not collected at all; and an MCP resource that carries a binary blob rather than text has no text to inspect, so it contributes nothing.

How the decision is made

1

The leg is sent to TrustGuard

Only the legs Direction selects are sent. A leg with nothing inspectable in it — an empty body, a tool result with no text anywhere — is skipped, and the event records why, so “not inspected” and “inspected, found nothing” stay distinguishable.
2

A block verdict refuses the request

An LLM caller gets 403. An MCP caller gets a JSON-RPC error. Either way, the response says the request was blocked by security policy. Where the finding has a detector or gate behind it, that name is in the message too, and the refusal carries identifiers you can use to find the request in Activity. See What the caller receives.The findings themselves are not in the response — no matched text, no confidence scores. Those are on the event and in Activity.A TrustGuard Ask action counts as a block here. Nothing on the gateway’s path can stop and put a confirmation in front of a person, so a verdict the gateway cannot ask about is refused rather than allowed.
3

A transform verdict rewrites the content in place

TrustGuard returns the masked payload and the gateway substitutes it, then lets the call continue. On the request leg the model or MCP server receives the masked version and never sees the original. On the response leg the caller does.
4

Otherwise the call continues untouched

A transform the gateway cannot map back onto the request blocks in Enforce. TrustGuard’s masked messages are matched back to the original by position and role, so a masked payload whose line count changed — a system prompt with surrounding whitespace trimmed, or a multi-line secret collapsed into a single masked token — is applied correctly, and the leg is recorded as transformed. If the masked messages cannot be mapped back at all — a role or message-count mismatch — the gateway treats it as a failure: in Enforce the leg is refused with 403 and recorded as blocked, marked degraded with the reason transform_failed. In Observe the original goes on and the failure is only recorded.
There are two Observe switches, and both have to be off for anything to be blocked. This policy’s mode decides whether the gateway acts on a verdict. The TrustGuard policy bound to the collector has its own mode, and in Observe it records detector actions without ever asking for a block or a transform. A gateway policy in Enforce against a TrustGuard policy in Observe blocks nothing, and nothing in this screen says so.

What the caller receives

A block on the LLM plane is an HTTP 403 with a JSON body. The body is the same whatever dialect the client speaks, and on either leg. direction says which leg was refused: input for the request, output for the model’s response.
An MCP call is refused with a JSON-RPC error over HTTP 200, because MCP clients treat a 4xx as a broken transport and drop the session. The code is -32001, the message is the same, and data carries the same body:
MCP
When several findings fired, the body names one: the enforced finding with the highest confidence. The rest, with their evidence and scores, are only in Activity. The 403 also carries an X-NeuralTrust-Block-Direction header with the same input or output. Every policy that refuses a leg with a 403 sets it, not only this one, so a client can tell the two legs apart without reading the body. A refusal that is not a verdict on the content does not carry it: the ones below. On a streamed response that this policy stops after it has started, the status is already 200. The stream ends with finish_reason content_filter and an error event whose object carries "direction": "output", for OpenAI-shaped and Responses clients. Anthropic, Gemini, Cohere and Bedrock clients get their usual stream ending, without the field. The other refusal has its own body: On MCP, this is a JSON-RPC error over HTTP 200, with TrustGuard’s body in data and the same headers on the response.

Modes and failures

The status codes are the LLM plane’s. On MCP, the same refusals arrive as the JSON-RPC errors in What the caller receives. “TrustGuard cannot be used” is any of: unreachable, a 5xx, a credential it refuses (including a 401 that survives a token refresh), unavailable entitlements (503), a gateway with no TrustGuard URL or credentials, or a call that does not answer in time. In every case the policy fails open. Failures caused by the content itself are the exception, as described in When TrustGuard cannot answer.
Observe does not mean “never refuses”. A TrustGuard rate limit refuses the request in Observe exactly as in Enforce — 429, with the retry-after and rate-limit headers TrustGuard returned forwarded to the caller — because it never reaches the point where the mode is read.
A TrustGuard outage forwards traffic uninspected. An outage, a timeout, a refused credential or a missing configuration lets the request go through, and the policy is recorded as Failed Open, with the reason on the event. The caller sees nothing. Watch for failed_open in Activity and on the failure count: silence is not evidence of clean traffic.
On a streamed response inspected block by block, a block TrustGuard could not inspect because the service was unavailable is let through, the other policies in the chain still inspect it, and the stream is recorded as failed_open when it ends. A mask that cannot be applied ends the stream in Enforce. After three failed blocks in a row this policy stops calling TrustGuard for the rest of that stream. Each inspected leg records one decision, and it is the first thing to read on the request’s Policies tab in Activity: allowed, reported, block, transformed, failed_open when a failed call was waved through, and failed_closed when the content itself caused the failure and Enforce refused it. Expect failed_open on a first run if something is misconfigured — a collector that was deleted, belongs to another gateway, or whose credential was refused looks exactly like an outage from here.

Streamed tool calls

When this policy inspects the response, a tool call on an OpenAI-shaped Chat Completions stream, and on Mistral, is held whole. The gateway keeps every argument fragment of that one choice until the call is complete and TrustGuard has returned a verdict, and it sends none of them before then. When the verdict allows the call, the held chunks are released together, in one burst at [DONE]. Several tool indexes on the same choice stay held together until every one of them is whole. When TrustGuard blocks that held call, or a short response held whole, the gateway answers HTTP 403 application/json before any SSE event, with no fragment and no [DONE]. The body has type trustguard_blocked and a message naming the detector. A stream that cannot be inspected as that one call is refused before any fragment is sent, whichever failure direction is set:
  • more than one choice, including n greater than 1 and a second choice later in the stream. The guard folds tool calls by index alone, so two choices that share an index become one arguments string, and a finish on one choice ends the stream
  • one chunk that carries several choices
  • a choice index that is not a JSON integer, such as "1" or 1.0
  • a tool whose name changes after the call opened, on the same choice and index, without a new call id
The hold is capped at 30 seconds, set by BEDROCK_NATIVE_TOOL_HOLD and shared with Bedrock native tool holds, and at 256 KiB of held stream bytes. When a cap is reached while the call is still open, TrustGuard fails open: the unfinished call is released uninspected and the stream is marked degraded with tool_input_uninspected.

Limits

  • A streamed response is inspected while it streams, and what the client already received stays with it. The gateway holds the start of the answer until TrustGuard has seen it, so a block there is a 403 before anything is sent. A block later in the stream ends it as described in What the caller receives, but the text delivered before the cut cannot be taken back.
  • On a long streamed response, each check reads only the latest 256 KiB. Text earlier than that is no longer sent, so a finding that needs it is missed. The event records the stream as degraded, with the reason accumulation_cap.
  • Direction is the only control over what is inspected. The policy is always active at every point in a request’s journey, and nothing stored on it changes that, so there is no second setting anywhere that narrows it. Direction is what decides whether a leg is actually sent to TrustGuard.
  • The request leg cannot be turned off for MCP separately from LLM. One policy covers both protocols within its scope.
  • Audio is never collected, on either leg. Image and file attachments are — but on the request leg only, and an MCP embedded resource carrying a binary blob rather than text has nothing to inspect.
  • An outage fails open; a content-caused failure blocks in Enforce. An outage, a rejected credential, a missing configuration, a timeout or an unparseable configuration forwards the traffic uninspected, whatever the mode. Content the gateway cannot read or TrustGuard cannot accept is refused in Enforce.

Verify the policy

Open the Playground, pick an application the policy applies to, and send these prompts in this order. Starting with the control means a failure tells you something specific. Before you start, confirm the TrustGuard policy bound to the collector is in Enforce and has the detector you are about to exercise enabled on Input. Otherwise step 3 proves nothing.
1

Control — the path works at all

Expect a normal reply and the decision allowed. If this fails, the problem is the application, the model or the collector binding — not the detector. Fix it before going on.
2

Sensitive data — masking works

Send a prompt containing something your TrustGuard policy masks, for example an email address.With a transform action, expect the decision transformed.Read the reply, not just the status. What the model answered must not contain the original value. That is what proves the model never received it.
3

Prompt injection — blocking works

Expect the decision block and a 403. Then confirm the model was never called: open the request in Activity, go to its Policies tab, and read Aggregated Latency. The Provider row should show no time at all. That the provider leg is empty is the evidence that matters.
4

MCP — the other protocol is covered too

The Playground cannot make this check — it sends prompts, not tool calls. So this one comes from a client already connected to an MCP server in this policy’s scope, whatever your agents use: have it call a tool with an argument that should trip the same detector.Expect a finding against the tool call, not only against chat traffic. This is the check most people skip, and it is the one that distinguishes this policy from every other guardrail.
Every verdict is recorded on the request in Activity, in Observe mode too: open the request and read its Policies tab, where this policy shows its decision and what TrustGuard found. The event schema documents the underlying fields if you need to match on them from an alert.

Troubleshooting