> ## Documentation Index
> Fetch the complete documentation index at: https://www.truefoundry.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Cato Networks

> Inspect, block, and anonymize prompts and model responses with Cato AI Security.

Use [Cato AI Security](https://www.catonetworks.com/platform/ai-security-for-applications/) with TrueFoundry AI Gateway to inspect prompts before they reach the model and model responses before they reach the caller. Cato can pass the payload through, block it, or replace messages with an anonymized copy.

## How the integration works

On each non-streaming chat request, the gateway calls `POST {base_url}/fw/v1/analyze` at the hooks you attach the guardrail to:

* **Input**, on the request the caller sent. In Mutate the result is applied before the model is called.
* **Output**, on the model's response, before it is returned to the caller

The body is an OpenAI chat payload: `model` when it is known, the full `messages` array (including the system prompt), and `tools` when the caller declared any. On the output hook the model's reply is appended to the conversation.

Cato answers with `required_action.action_type`:

| Cato action | Mutate | Validate |
| - | - | - |
| Absent, `monitor_action`, or any unrecognized value | Pass the payload through unchanged | Same |
| `block_action` | Violation | Violation |
| `anonymize_action` | Replace the messages with `redacted_chat.all_redacted_messages` and continue | Violation. The payload is not changed. |

A violation is handled by the [enforcing strategy](#enforcing-strategy). When the request is rejected, the caller receives a `400` with type `guardrail_checks_failed`.

### MCP tool calls

The guardrail can also be attached to MCP tool hooks. Tool arguments are sent to Cato as `user` messages, one per argument, and the tool result is sent as a single `assistant` message. In Mutate, anonymized arguments and results are written back to the tool call.

<Note>
  The guardrail runs on the input and output of chat requests and on MCP tool calls. Output inspection is skipped for streamed responses.
</Note>

## Prerequisites

* An API key issued by Cato for the AI Security guard
* The Cato API base URL for your region, or the URL of a Cato Outpost in your environment
* Network access from the gateway to that URL

## Add the Cato Networks guardrail

<Steps>
  <Step title="Select Cato Networks">
    In TrueFoundry, go to **AI Gateway → Guardrails**, create or open a guardrail group, and select **Cato Networks** under **External Providers**.
  </Step>

  <Step title="Configure the guardrail">
    * **Name**: A name such as `cato`.
    * **API Key**: The key from the Cato guard. TrueFoundry stores it as a secret and sends it as `Authorization: Bearer`.
    * **Base URL**: The Cato endpoint, for example `https://api.aisec.catonetworks.com`, or your Outpost URL. Trailing slashes are ignored. This field is required.
    * **Operation**:
      * **Mutate** (default) follows Cato's contract. On `anonymize_action` the messages are replaced with Cato's redacted versions and the request continues. Mutate guardrails run one after another, before the model is called.
      * **Validate** never changes the payload. A `block_action` or an `anonymize_action` counts as a violation. Validate guardrails run in parallel with the model request.
    * **Enforcing Strategy**: See [Enforcing strategy](#enforcing-strategy).
    * **Priority**: Order among other mutate guardrails. Lower values run first. Applies to Mutate only.
  </Step>

  <Step title="Attach the guardrail">
    Save the guardrail group, then attach it to the LLM input hook, the LLM output hook, or both through a [guardrail policy](/docs/ai-gateway/guardrails-configuration).
  </Step>
</Steps>

### Enforcing strategy

| Strategy | Violation (block or, in Validate, anonymize) | Cato unreachable or returns an error |
| - | - | - |
| **Enforce** | Request is rejected | Request is rejected |
| **Enforce But Ignore On Error** | Request is rejected | Request continues |
| **Audit** (Validate only) | Recorded, request continues | Request continues |

<Warning>
  Validate guardrails run in parallel with the model request. When a Validate guardrail rejects a request, the prompt has already been sent to the model. To make the guardrail finish before the model is called, turn off **Run Guardrails in Parallel with Model Request** in the gateway guardrail settings, or use Mutate.
</Warning>

## Verify the integration

Select the guardrail on a request with the `X-TFY-GUARDRAILS` header. The selector format is `<group>/<guardrail-name>`.

```bash theme={"dark"}
curl -X POST "https://<your-gateway-url>/chat/completions" \
  -H "Authorization: Bearer ${TFY_API_KEY}" \
  -H "Content-Type: application/json" \
  -H 'X-TFY-GUARDRAILS: {"llm_input_guardrails":["my-group/cato"],"llm_output_guardrails":["my-group/cato"]}' \
  -d '{
    "model": "my-account/my-model",
    "messages": [
      {"role": "system", "content": "You are a helpful assistant."},
      {"role": "user", "content": "Hi, my SSN is 123-45-6789"}
    ]
  }'
```

What comes back depends on the policy configured in Cato for your guard.

**Cato returns nothing.** The response is a normal completion. Each check reports `decision: allow`.

```json theme={"dark"}
{
  "guardrail_checks": {
    "input_guardrails": [
      {
        "guardrail_integration": "my-group/cato",
        "result": "passed",
        "data": { "decision": "allow", "action_type": null },
        "transformed": false
      }
    ]
  }
}
```

**Cato anonymizes, guardrail is Mutate.** The model sees the masked text, and the check reports `transformed: true`.

```json theme={"dark"}
{
  "guardrail_integration": "my-group/cato",
  "result": "passed",
  "data": { "decision": "anonymize" },
  "transformed": true
}
```

**Cato blocks.** The request is rejected with `400`. The message names the detection categories Cato reported, such as `SSN`, and never the text that matched. Cato's `detection_message` is not returned, because it quotes the matched text. The `analysis_result` on the check keeps only each policy's name and the category and certainty of each detection. The matched values, their positions and the entity lists are removed. If Cato reports no category, the message is `Content blocked by Cato Networks`.

```json theme={"dark"}
{
  "status": "failure",
  "message": "Input Guardrail checks failed for integrations: [my-group/cato] - Details: Cato Networks policy violation (one)",
  "error": { "type": "guardrail_checks_failed", "code": "400" },
  "error_origin_level": "guardrails_input",
  "guardrail_checks": {
    "input_guardrails": [
      {
        "guardrail_integration": "my-group/cato",
        "result": "failed",
        "data": {
          "decision": "block",
          "message": "Cato Networks policy violation (one)",
          "analysis_result": {
            "policy_drill_down": {
              "<policy-id>": {
                "policy_name": "testone - testone",
                "detections": [{ "type": "one", "certainty": "HIGH" }]
              }
            }
          }
        },
        "transformed": false
      }
    ]
  }
}
```

In Validate, an `anonymize_action` produces the same kind of `failed` check with `decision: anonymize`, and the same category-only message and redacted `analysis_result`.

## Per-application policy

Every analyze call sends `x-cato-gateway-key-alias`. Cato uses that alias, not the key secret, to select a policy.

TrueFoundry takes the alias from the authenticated caller, never from the request:

1. The personal access token name, when the request is authenticated with one
2. Otherwise the virtual account, user, or agent name

A caller cannot choose their own alias, so one application cannot have its traffic evaluated under another application's policy. If no alias can be determined, the request is rejected.

Other request headers whose names start with `x-cato-` are forwarded to Cato unchanged, as Cato requires. The exceptions are headers that identify the caller or select a policy, which only the gateway sets: `x-cato-gateway-key-alias`, `x-cato-gateway-key-name`, `x-cato-user-email`, and `x-cato-call-id`. If a caller sends one of these, it is dropped.

Name the guard in Cato after the alias you expect, so each application can have its own policy.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.