---
schema_version: "1"
id: 894eca2fe30099618ff174f8362b5fb1030f7ef9fb6b90fb78f76c5e63ab2c24
title: F5 Guardrails Policy
collection: mulesoft
version: current
locale: en-us
portal_url: https://docs.salesforce.com/mulesoft/current/en-us/gateway/latest/policies-included-f5-guardrails.md
canonical_url: https://docs.mulesoft.com/gateway/latest/policies-included-f5-guardrails
source_site: docs.mulesoft.com
content_type: documentation
content_hash: 48ade7dec4f06a478e5c9202598876f54273a21e08e95c8f145da25e445e159e
description: MuleSoft Documentation Site
release: "1.14"
latest: true
---
---
product: Omni Gateway
version: 1.14
is-latest-version: true
keywords: api gateway, flex gateway, gateway, policy, llm, content safety, f5, calypsoai, guardrails, redaction
---

# F5 Guardrails Policy

> For the full documentation index, see: https://docs.mulesoft.com/llms.txt

<table><colgroup><col> <col></colgroup><tbody><tr><td><p><strong>Policy Name</strong></p></td><td><p>F5 Guardrails Policy</p></td></tr><tr><td><p><strong>Summary</strong></p></td><td><p>Evaluates LLM prompts and responses against F5 AI Guardrails, blocking, flagging, or redacting flagged content</p></td></tr><tr><td><p><strong>Category</strong></p></td><td><p>LLM</p></td></tr><tr><td><p><strong>First Omni Gateway version available</strong></p></td><td><p>v1.14.0</p></td></tr><tr><td><p><strong>Release Notes</strong></p></td><td><p><a href="https://docs.mulesoft.com/release-notes/gateway/policies/f5-guardrails-release-notes">F5 Guardrails Policy</a></p></td></tr><tr><td rowspan="2"><p><strong>Returned Status Codes</strong></p></td><td><p>200 - OK: Content blocked by F5 AI Guardrails. The response is a native content-filter response for the caller’s LLM format.</p></td></tr><tr><td><p>503 - Service Unavailable: F5 scan call failed or returned no verdict (only when fail-open is disabled)</p></td></tr></tbody></table>

## Summary

The F5 Guardrails policy provides content moderation for LLMs by evaluating prompts and responses
against [F5 AI Guardrails](https://docs.aisecurity.f5.com/). The policy calls the F5
(`POST /backend/v1/scans`) API and enforces the returned verdict at the gateway before the request
reaches the upstream LLM (request phase) or before the response is returned to the client (response
phase).

Which F5 scanners run and how they behave (harmful content, prompt injection, PII and other
sensitive data, data leakage, and so on) is owned by your F5 project configuration, not the policy.
The policy is the enforcement point that turns an F5 verdict into a gateway action:

- **Allow**: Cleared content is forwarded unchanged.

- **Flag**: Flagged content is allowed but a policy violation is recorded (audit).

- **Redact**: Sensitive content is masked in place using F5’s redaction, then forwarded.

- **Reject**: Blocked content is rejected. The client receives a native content-filter response for
  its LLM format (OpenAI, Anthropic, or Gemini) with HTTP status `200`.

The policy operates in two independent phases:

- **Request phase**: Sends the whole request body to F5 with `scanDirection: request`. Rejected
  prompts never reach the LLM.

- **Response phase**: Sends the whole LLM response body to F5 with `scanDirection: response` before
  returning it to the client. This response phase is off by default.

Every scan emits observability headers, a scan ID for correlation with the F5 console, a per-call
metric, and records a policy violation for the **Flag** or **Reject** outcomes.

## Before You Begin

Before configuring this policy, you need:

1.  **F5 AI Guardrails access** (SaaS tenant or a self-hosted deployment).

2.  **An F5 AI Guardrails endpoint URL**, for example, `https://us1.calypsoai.app`.

3.  **An F5 API token** issued from the F5 console.

4.  **(Optional) An F5 project ID or friendly ID** whose F5 scanner configuration the scan should
    use.

If you connect to F5 SaaS, ensure the Omni Gateway can reach the F5 host outbound.

The policy reads the `x-input-format` header, which the LLM proxy sets, to identify the caller’s LLM
format: `openai`, `anthropic`, or `gemini`. If the header is absent, the policy uses `openai`.
Traffic with any other format value, or a non-JSON body, passes through unscanned.

## Configuring Policy Parameters

### Omni Gateway Local Mode

The F5 Guardrails policy isn’t supported in Local Mode.

### Managed Omni Gateway and Omni Gateway Connected Mode

When you apply the policy from the UI, the following parameters are displayed:

### Basic Configuration

<table><colgroup><col> <col> <col></colgroup><thead><tr><th>Element</th><th>Required</th><th>Description</th></tr></thead><tbody><tr><td><div><div><p>F5 AI Guardrails Endpoint</p></div></div></td><td><div><div><p>Yes</p></div></div></td><td><div><div><p>F5 AI Guardrails base URL, for example, <code>https://us1.calypsoai.app</code>. The policy appends <code>/backend/v1/scans</code> at call time.</p></div></div></td></tr><tr><td><div><div><p>F5 API Token</p></div></div></td><td><div><div><p>Yes</p></div></div></td><td><div><div><p>F5 AI Guardrails API token. Enter the raw token without a <code>Bearer</code> prefix. The policy sends it as <code>Authorization: Bearer &lt;token&gt;</code> on every scan call. This value is sensitive and is never logged.</p></div></div></td></tr><tr><td><div><div><p>F5 Project</p></div></div></td><td><div><div><p>No</p></div></div></td><td><div><div><p>F5 project ID or friendly ID. When set, it’s sent as the <code>project</code> field so the scan uses that project’s F5 scanner configuration. When omitted, the token’s globally available F5 scanners are used.</p></div></div></td></tr><tr><td><div><div><p>Moderate Request</p></div></div></td><td><div><div><p>No</p></div></div></td><td><div><div><p>When enabled (default), the policy evaluates the user prompt against F5 AI Guardrails (<code>scanDirection: request</code>) before forwarding to the upstream LLM. Rejected prompts never reach the LLM.</p></div></div></td></tr><tr><td><div><div><p>Moderate Response</p></div></div></td><td><div><div><p>No</p></div></div></td><td><div><div><p>When enabled, the policy evaluates the LLM response (<code>scanDirection: response</code>) before returning it to the client. Default: disabled.</p></div><div><p>Streaming responses (<code>text/event-stream</code>) are also scanned. The policy buffers the entire stream and holds the response until the scan completes. This breaks the streaming experience for the client and increases latency and memory use.</p></div></div></td></tr></tbody></table>

### Advanced Configuration

<table><colgroup><col> <col> <col></colgroup><thead><tr><th>Element</th><th>Required</th><th>Description</th></tr></thead><tbody><tr><td><div><div><p>Apply Redaction</p></div></div></td><td><div><div><p>No</p></div></div></td><td><div><div><p>When enabled (default), a <code>redacted</code> outcome rewrites the request or response body with the F5-supplied masked text and lets traffic continue. When disabled, a <code>redacted</code> outcome is handled like a <code>blocked</code> outcome and rejected with a native content-filter response (HTTP <code>200</code>). See <a href="#outcomes-and-actions">Outcomes and Actions</a>.</p></div></div></td></tr><tr><td><div><div><p>Flag Only (Audit Mode)</p></div></div></td><td><div><div><p>No</p></div></div></td><td><div><div><p>When enabled, the scan carries <code>flagOnly: true</code> so blockable F5 scanners return <code>flagged</code> instead of <code>blocked</code>, and the policy never rejects for an F5 scanner hit. A policy violation is still recorded. Use this to observe what F5 would block without enforcing. Default: disabled.</p></div></div></td></tr><tr><td><div><div><p>Disabled Scanners</p></div></div></td><td><div><div><p>No</p></div></div></td><td><div><div><p>F5 scanner IDs to disable, sent as the <code>disabled</code> array. Applies to both phases unless overridden per phase by Request-Phase or Response-Phase Scanner Overrides. Overrides the project or token defaults for the named F5 scanners.</p></div></div></td></tr><tr><td><div><div><p>Force-Enabled Scanners</p></div></div></td><td><div><div><p>No</p></div></div></td><td><div><div><p>F5 scanner IDs to force-enable, sent as the <code>forceEnabled</code> array, even if disabled in the project. Applies to both phases unless overridden per phase.</p></div></div></td></tr><tr><td><div><div><p>Request-Phase Scanner Overrides</p></div></div></td><td><div><div><p>No</p></div></div></td><td><div><div><p>Per-phase F5 scanner selection for the request (prompt) scan, with optional <code>disabledScanners</code> and <code>forceEnabledScanners</code> arrays. See <a href="#per-phase-scanner-selection">Per-Phase Scanner Selection</a>.</p></div></div></td></tr><tr><td><div><div><p>Response-Phase Scanner Overrides</p></div></div></td><td><div><div><p>No</p></div></div></td><td><div><div><p>Per-phase F5 scanner selection for the response (completion) scan. Same shape as Request-Phase Scanner Overrides. See <a href="#per-phase-scanner-selection">Per-Phase Scanner Selection</a>.</p></div></div></td></tr><tr><td><div><div><p>Verbose</p></div></div></td><td><div><div><p>No</p></div></div></td><td><div><div><p>When enabled, the policy requests more detailed scanner results from F5. The extra detail enriches the reason header and debug logs. Default: disabled.</p></div></div></td></tr><tr><td><div><div><p>API Timeout (ms)</p></div></div></td><td><div><div><p>No</p></div></div></td><td><div><div><p>Per-request timeout for each F5 scan call in milliseconds. Must be between <code>1000</code> and <code>30000</code>. Default: <code>5000</code>.</p></div></div></td></tr><tr><td><div><div><p>Fail Open</p></div></div></td><td><div><div><p>No</p></div></div></td><td><div><div><p>Determines behavior when the F5 scan call fails, times out, or returns no verdict:</p></div><div><ul><li><p>Disabled (default): Rejects with HTTP <code>503</code>.</p></li><li><p>Enabled: Allows traffic to proceed unscanned (fail-open mode).</p></li></ul></div></div></td></tr></tbody></table>

## How This Policy Works

The F5 Guardrails policy integrates with F5 AI Guardrails to evaluate LLM prompts and responses.

### Request and Response Moderation

The policy supports independent evaluation for request and response:

1.  **Request Phase** (when Moderate Request is enabled):

    1.  The policy resolves the caller’s LLM format from the `x-input-format` header. Traffic in an
        unsupported format, or with a non-JSON or empty body, passes through unscanned.

    2.  The policy sends the whole request body to `POST {endpoint}/backend/v1/scans` with
        `scanDirection: request`.

    3.  The policy enforces the returned outcome. See [Outcomes and Actions](#outcomes-and-actions).

    4.  If the prompt passes (cleared or flagged), the policy forwards the request to the upstream
        LLM. On `redacted`, it forwards a masked version. On `blocked`, it returns a native
        content-filter response with HTTP `200`.

2.  **Response Phase** (when Moderate Response is enabled):

    1.  The policy buffers the LLM response.

    2.  The policy sends the whole response body to F5 with `scanDirection: response`.

    3.  The policy enforces the returned outcome. See [Outcomes and Actions](#outcomes-and-actions).

    4.  If the response passes, the policy forwards it unchanged. On `redacted`, the body is
        rewritten with the masked body. On `blocked`, the response is rewritten to a native
        content-filter response with HTTP `200`.

        > [!NOTE] Streaming responses (`text/event-stream`) are buffered and scanned when Moderate
        > Response is enabled. The client doesn’t receive the response until the scan completes.

When both phases scan, the client-visible response headers reflect the response-phase decision. They
reflect the request-phase decision only when the response isn’t scanned.

### Outcomes and Actions

The policy enforces the global `result.outcome` returned by F5:

<table><colgroup><col> <col> <col></colgroup><thead><tr><th>F5 Outcome</th><th>Action</th><th>Effect</th></tr></thead><tbody><tr><td><div><div><p><code>cleared</code></p></div></div></td><td><div><div><p>Allow</p></div></div></td><td><div><div><p>Content is forwarded unchanged. No policy violation recorded.</p></div></div></td></tr><tr><td><div><div><p><code>flagged</code></p></div></div></td><td><div><div><p>Flag</p></div></div></td><td><div><div><p>Traffic continues, a policy violation is recorded, and the failed F5 scanner names populate the reason header. This is the outcome for audit (non-blocking) F5 scanners and for every blockable F5 scanner when <strong>Flag Only</strong> is enabled.</p></div></div></td></tr><tr><td><div><div><p><code>redacted</code></p></div></div></td><td><div><div><p>Redact</p></div></div></td><td><div><div><p>When Apply Redaction is enabled (default), the whole request or response body is replaced with the masked body that F5 returns, traffic continues, and a policy violation is recorded. If F5 returns no masked body, the policy fails closed and rejects the content with the reason <code>redaction_failed</code>. When Apply Redaction is disabled, the outcome is treated as <code>blocked</code>.</p></div></div></td></tr><tr><td><div><div><p><code>blocked</code></p></div></div></td><td><div><div><p>Reject</p></div></div></td><td><div><div><p>The request phase returns a native content-filter response instead of calling the LLM; the response phase rewrites the LLM response to a native content-filter response. Both use HTTP <code>200</code>. A policy violation is recorded. Any unrecognized outcome is also treated as <code>blocked</code> so an unexpected verdict never silently passes.</p></div></div></td></tr><tr><td><div><div><p><code>none</code> (no verdict)</p></div></div></td><td><div><div><p>Indeterminate</p></div></div></td><td><div><div><p>An empty or <code>none</code> outcome isn’t treated as a block. It’s resolved by the Fail Open setting: fail-closed returns an HTTP <code>503</code> error with the reason <code>none_response</code>, fail-open passes traffic through unscanned.</p></div></div></td></tr></tbody></table>

Every non-`cleared` outcome records a policy violation and adds the failed F5 scanner names to the
reason header.

### Per-Phase Scanner Selection

The `disabled` and `forceEnabled` F5 scanner lists sent on each scan are resolved per phase, so the
request (prompt) and response (completion) phases can target different F5 scanner sets:

- The **request phase** uses Request-Phase Scanner Overrides when set, otherwise the global
  **Disabled Scanners** and **Force-Enabled Scanners** lists.

- The **response phase** uses response-phase scanner overrides with the same global fallback.

- Each list falls back independently. An explicitly empty per-phase array (`[]`) replaces (clears)
  the global list for that phase; an unset array falls back to the global list.

When neither per-phase override is set, the global lists apply to both phases. If a per-phase
override is set for a phase whose moderation is disabled, the override can never take effect, and
the policy logs a startup warning.

## Example Configurations

### Minimal Configuration — Both Phases, Enforce and Redact

`moderateRequest` and `applyRedaction` default to `true`, so the prompt is scanned, sensitive data
is masked in place on a `redacted` verdict, and blocked content returns a native content-filter
response. `moderateResponse` defaults to `false`. Add it to also scan the LLM response.

```yaml
- policyRef:
    name: f5-guardrails-policy-v1-0-impl
    namespace: default
  config:
    f5Endpoint: https://us1.calypsoai.app
    f5ApiToken: "${F5_GUARDRAILS_TOKEN}"
    f5Project: "<your-f5-project-id>"
```

### Audit Mode — Observe Without Enforcing

No request is ever blocked. Every F5 scanner hit surfaces as `flag` with a policy violation and
reason header. Use this to measure impact before switching to enforcement.

```yaml
- policyRef:
    name: f5-guardrails-policy-v1-0-impl
    namespace: default
  config:
    f5Endpoint: https://us1.calypsoai.app
    f5ApiToken: "${F5_GUARDRAILS_TOKEN}"
    f5Project: "<your-f5-project-id>"
    advancedConfiguration:
      flagOnly: true
      applyRedaction: false
```

### Request-Only, Fail-Open, Custom Scanners

Only the prompt is scanned, one F5 scanner is disabled for this route, and if F5 is unreachable the
request proceeds unscanned (with the reason header emitted).

```yaml
- policyRef:
    name: f5-guardrails-policy-v1-0-impl
    namespace: default
  config:
    f5Endpoint: https://eu1.calypsoai.app
    f5ApiToken: "${F5_GUARDRAILS_TOKEN}"
    f5Project: "prod-chat"
    moderateRequest: true
    moderateResponse: false
    advancedConfiguration:
      disabledScanners: ["01983d0c-f1cc-700a-ab56-6600efc7dfb9"]
      apiTimeoutMs: 8000
      failOpen: true
```

### Per-Phase Scanner Selection

The request scan and response scan target independent F5 scanner sets. The request phase clears the
global disable list and force-enables an F5 scanner; the response phase keeps the global disable and
adds another F5 scanner.

```yaml
- policyRef:
    name: f5-guardrails-policy-v1-0-impl
    namespace: default
  config:
    f5Endpoint: https://us1.calypsoai.app
    f5ApiToken: "${F5_GUARDRAILS_TOKEN}"
    f5Project: "prod-chat"
    advancedConfiguration:
      disabledScanners: ["01983d0c-f1cc-700a-ab56-6600efc7dfb9"]
      requestScanners:
        disabledScanners: []
        forceEnabledScanners: ["019f3a1b-2c3d-4e5f-6071-8293a4b5c6d7"]
      responseScanners:
        forceEnabledScanners: ["01a2b3c4-d5e6-7089-abcd-ef0123456789"]
```

## See Also

- [F5 AI Guardrails documentation](https://docs.aisecurity.f5.com/)

- [Azure Content Safety Policy](https://docs.mulesoft.com/gateway/latest/policies-included-azure-content-safety)

- [Amazon Bedrock Guardrails Policy](https://docs.mulesoft.com/gateway/latest/policies-included-bedrock-guardrails)

- [Creating and Managing Model Proxies](https://docs.mulesoft.com/general/model-proxy)

- [Applying Model Proxy Policies](https://docs.mulesoft.com/general/model-proxy-policies)
