Skip to main content

Content Guard

The Content Guard middleware detects and processes sensitive or restricted content in requests and responses. It allows you to:

  1. Block specific content (such as personally identifiable information or disallowed phrases) in either requests or responses, preventing it from reaching any upstream service or being returned to the client.
  2. Mask sensitive content in both requests and responses, preserving confidentiality and ensuring compliance.

For the AI Gateway, the Content Guard middleware empowers enterprises to responsibly deploy LLMs by ensuring that sensitive or non-compliant content never reaches AI models—or end users. Whether protecting customer privacy, enforcing corporate policy, or complying with regulations like HIPAA and GDPR, Content Guard adds a critical safety net for all AI-driven interactions.

Key Features and Benefits

  • Prevent data leakage by blocking PII or sensitive information in inputs and outputs
  • Mask content instead of blocking, maintaining UX while enforcing policies
  • Use custom detection rules for internal codes or region-specific regulations
  • Track violations and compliance metrics through integrated observability

Requirements

  • AI Gateway must be enabled:

    helm upgrade traefik -n traefik --wait \
    --reuse-values \
    --set hub.experimental.aigateway=true \
    traefik/traefik
  • An external content detection engine is required. Currently, we support presidio as the content detection engine.

  • Configure the detection engine endpoint in the middleware definition.

How It Works

When the Content Guard middleware intercepts an HTTP request or response:

  • Identify Relevant JSON Fields: You specify which parts of the JSON body to analyze for sensitive data. For example, you might target user messages in a request or AI-generated text in a response.

  • Analyze Detected Text: The external engine (Presidio) checks whether the targeted text contains any specified “entities” (e.g., PERSON, EMAIL_ADDRESS, LOCATION). For a complete list of supported entities, see Presidio Supported Entities

  • Block or Mask

    • Block: If you mark a rule to “block” and the engine finds a match, the middleware returns a 403 Forbidden, stopping the request or response.
    • Mask: If instead you specify a “mask,” the matched portions are replaced with a chosen character pattern (for example, using * or #), optionally revealing a few characters from the beginning or end.
  • Custom Entities: In addition to built-in Presidio entities, you can define your own entity patterns. This can be helpful for organization-specific data formats like employee IDs or internal codes. For more details, please see the Custom Entities section.

Configuration Example

Below is an example demonstrating how to block certain content in requests and mask it in responses:

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
namespace: traefik
name: content-guard
spec:
plugin:
content-guard:
engine:
presidio:
host: http://presidio
language: en

request:
rules:
- jsonPaths:
- ".messages[].content"
block: true
entities:
- PERSON
- LOCATION
response:
rules:
- jsonPaths:
- ".choices[].message.content"
mask:
char: "*"
unmaskFromLeft: 2
unmaskFromRight: 2
entities:
- PERSON
- LOCATION

Configuation Options

KeyDescriptionRequiredDefault
engine.presidio.hostThe base URL of your Presidio analyzer instance.yes
engine.presidio.languageLanguage code used by Presidio for detection (e.g., en).yes
engine.presidio.entitiesOptional list of entity types to detect (e.g. PHONE_NUMBER, EMAIL_ADDRESS). If not set, Presidio uses all known entity types.no
request.rulesAn array of rule objects for incoming traffic. Each rule can specify jsonPaths, block, mask, and a list of entities.no
request.rules[].jsonPathsA list of gojq-style JSON paths to scan in the request (e.g., ".messages[].content").yes
request.rules[].blockIf true, any match triggers 403 Forbidden for the request.nofalse
request.rules[].maskDefines how matched text is masked if block is false. This object can contain char, unmaskFromLeft, unmaskFromRight.no
request.rules[].mask.charCharacter used to replace matched text.yes (if using mask)*
request.rules[].mask.unmaskFromLeftNumber of characters to leave unmasked at the start of a match.no0
request.rules[].mask.unmaskFromRightNumber of characters to leave unmasked at the end of a match.no0
request.rules[].entitiesList of entities to look for. If omitted, Presidio attempts to detect all known entities. For a complete list of supported entities, see Presidio Supported Entitiesno
response.rulesAn array of rule objects for outgoing traffic. Each rule can also specify jsonPaths, block, mask, entities.no
response.rules[].jsonPathsA list of JSON paths to scan in the response body.yes
response.rules[].blockIf true, any match triggers 403 Forbidden for the response.nofalse
response.rules[].maskDefines how matched text is masked if block is false. Can contain char, unmaskFromLeft, unmaskFromRight.no
response.rules[].mask.charCharacter used to replace matched text.yes (if using mask)*
response.rules[].mask.unmaskFromLeftNumber of characters to leave unmasked at the start of a match.no0
response.rules[].mask.unmaskFromRightNumber of characters to leave unmasked at the end of a match.no0
response.rules[].entitiesList of entities to detect. If omitted, Presidio attempts to detect all known entities. For a complete list of supported entities, see Presidio Supported Entitiesno

Custom Entities

You can define additional entities for Presidio to detect (such as specialized IDs or formats). These are typically added in Presidio’s configuration itself, or via its “custom analyzer” endpoints. Once added, you can reference them in the entities array like built-in types. For more details, please see the Presidio Custom Analyzer documentation.

Request vs. Response Rules

  • Request Rules: Often used to block disallowed content before it ever arrives at the AI. For example, if a request includes personal information in .messages[].content, you can instantly return a 403 Forbidden.
  • Response Rules: If your AI might return sensitive data (like phone numbers or addresses), you can mask that content before sending the response to the user. In unusual cases, you can also block the entire response.