|
| 1 | +--- |
| 2 | +min_version: |
| 3 | + ai-gateway: '2.0' # TODO: confirm. Aha AI-46 targets the 2.3 GA release (2026-10-29) as Tech Preview. |
| 4 | +works_on: |
| 5 | + - konnect |
| 6 | +products: |
| 7 | + - ai-gateway |
| 8 | +content_type: plugin |
| 9 | +tech_preview: true |
| 10 | +categories: |
| 11 | + - ai |
| 12 | +tags: |
| 13 | + - ai |
| 14 | + - mcp |
| 15 | + - dlp |
| 16 | + - security |
| 17 | +related_resources: |
| 18 | + - text: AI PII Sanitizer Policy |
| 19 | + url: /ai-gateway/policies/ai-sanitizer/ |
| 20 | + - text: AI MCP Server |
| 21 | + url: /ai-gateway/entities/ai-mcp-server/ |
| 22 | + - text: AI Policy |
| 23 | + url: /ai-gateway/entities/ai-policy/ |
| 24 | + - text: MCP version support |
| 25 | + url: /ai-gateway/mcp-version-support/ |
| 26 | + - text: Model Context Protocol specification |
| 27 | + url: https://modelcontextprotocol.io/ |
| 28 | +published: false |
| 29 | +--- |
| 30 | + |
| 31 | +<!-- TODO: Drafted from kong-ee PR #23501 (draft), Aha AI-46, and the MCP PII sanitizer PRD and design doc. No Konnect API spec was available. Confirm every field name, default, scope, and error behavior against the spec, then remove `published: false`. The Aha description and PRD still describe the earlier `mcp-pii-sanitizer` design (`sanitization_mode`, per-leaf calls). PR #23501 is the source for this page. --> |
| 32 | + |
| 33 | +The AI MCP Sanitizer Policy detects and redacts personally identifiable information (PII) in [Model Context Protocol (MCP)](/mcp/) `tools/call` traffic on {{site.ai_gateway}}. |
| 34 | +It can sanitize the arguments an agent sends to a tool, the result a tool returns, or both. |
| 35 | + |
| 36 | +MCP tools often front systems of record such as CRMs, ticketing tools, and medical or financial databases, where arguments and results routinely carry PII. |
| 37 | +The [AI PII Sanitizer Policy](/ai-gateway/policies/ai-sanitizer/) can't protect this traffic, because it expects chat-completion bodies and not MCP's JSON-RPC `params` and `result` structures. |
| 38 | +The AI MCP Sanitizer Policy adds PII sanitization to MCP traffic proxied by an [AI MCP Server](/ai-gateway/entities/ai-mcp-server/). |
| 39 | + |
| 40 | +The Policy uses the same PII service, PII categories, custom patterns, blocking, and recovery options as the AI PII Sanitizer Policy. |
| 41 | +If you already use that Policy, the connection and detection settings work the same way. |
| 42 | + |
| 43 | +## What gets sanitized |
| 44 | + |
| 45 | +The Policy sanitizes the `tools/call` method only. |
| 46 | +It doesn't sanitize other MCP methods, such as `resources/read` or `prompts/get`. |
| 47 | + |
| 48 | +You choose what to sanitize with `sanitize_targets`. |
| 49 | +Each target names a location in the MCP protocol instead of an abstract direction: |
| 50 | + |
| 51 | +{% table %} |
| 52 | +columns: |
| 53 | + - title: Target |
| 54 | + key: target |
| 55 | + - title: Direction |
| 56 | + key: direction |
| 57 | + - title: Use it to |
| 58 | + key: use |
| 59 | +rows: |
| 60 | + - target: "`tool_arguments`" |
| 61 | + direction: "The `tools/call` request, from {{site.ai_gateway}} to the tool server" |
| 62 | + use: Prevent a third-party tool from receiving user data. |
| 63 | + - target: "`tool_results`" |
| 64 | + direction: "The `tools/call` response, from the tool server through {{site.ai_gateway}} to the calling agent" |
| 65 | + use: Prevent data from a system of record from appearing in the LLM context. |
| 66 | +{% endtable %} |
| 67 | + |
| 68 | +You can enable either target, or both. |
| 69 | +The default is `tool_arguments`. |
| 70 | + |
| 71 | +{{site.ai_gateway}} sanitizes only the fields that carry user data: |
| 72 | + |
| 73 | +* **Sanitized:** string values in the tool call arguments, `text` entries in `result.content[]`, and string values in `result.structuredContent`. |
| 74 | +* **Not sanitized:** the tool name, JSON-RPC envelope fields such as `jsonrpc` and `id`, `result.isError`, `result._meta`, and `result.content[]` entries of type `image`, `audio`, or `resource`. |
| 75 | + |
| 76 | +Rewriting tool names and protocol fields would break tool dispatch, access control, and protocol negotiation. |
| 77 | +Skipping binary content avoids sending large payloads to the PII service for no benefit. |
| 78 | + |
| 79 | +<!-- TODO: confirm the exact set of sanitized fields against the final PR and spec. --> |
| 80 | + |
| 81 | +## How it works |
| 82 | + |
| 83 | +The AI MCP Sanitizer Policy sanitizes a `tools/call` request and its result in the following order: |
| 84 | + |
| 85 | +1. A client sends a `tools/call` request to the AI MCP Server. |
| 86 | +1. {{site.ai_gateway}} authorizes the request and applies rate limiting. |
| 87 | + {{site.ai_gateway}} rejects a request that fails either check before it calls the PII service. |
| 88 | +1. If `tool_arguments` is targeted, the Policy sends the argument text to the PII service and replaces each value with its sanitized version. |
| 89 | +1. {{site.ai_gateway}} forwards the sanitized request to the tool server. |
| 90 | +1. If `tool_results` is targeted, {{site.ai_gateway}} holds the complete result from the tool server, the Policy sends its text to the PII service, and {{site.ai_gateway}} returns the sanitized result to the agent. |
| 91 | + |
| 92 | +{% mermaid %} |
| 93 | +sequenceDiagram |
| 94 | + autonumber |
| 95 | + participant Agent as MCP client |
| 96 | + participant Kong as AI MCP Server |
| 97 | + participant PII as PII service |
| 98 | + participant Tool as MCP tool server |
| 99 | + |
| 100 | + Agent->>Kong: tools/call request |
| 101 | + Kong->>Kong: Authorize and rate limit |
| 102 | + Kong->>PII: Send argument text (tool_arguments) |
| 103 | + PII->>Kong: Return sanitized text |
| 104 | + Kong->>Tool: Forward sanitized request |
| 105 | + Tool->>Kong: Return result |
| 106 | + Kong->>PII: Send result text (tool_results) |
| 107 | + PII->>Kong: Return sanitized text |
| 108 | + Kong->>Agent: Return sanitized result |
| 109 | +{% endmermaid %} |
| 110 | + |
| 111 | +{:.info} |
| 112 | +> {{site.ai_gateway}} never sanitizes the authentication tools that it handles itself, because their arguments are credentials and not user PII. |
| 113 | +<!-- TODO: confirm the user-facing name of these tools --> |
| 114 | +
|
| 115 | +### Supported server types |
| 116 | + |
| 117 | +The Policy works with the `passthrough-listener`, `listener`, and `conversion-listener` AI MCP Server types. |
| 118 | +It handles both JSON and SSE-framed responses, and re-frames sanitized SSE responses automatically. |
| 119 | +<!-- TODO: confirm behavior for `conversion-only` and `upstream-server` types --> |
| 120 | + |
| 121 | +## Streaming and performance trade-offs |
| 122 | + |
| 123 | +Sanitizing a tool result requires the complete result before {{site.ai_gateway}} sends any of it to the agent. |
| 124 | +The PII service scores text as a whole, and a placeholder can't replace bytes that {{site.ai_gateway}} has already sent. |
| 125 | +For that reason, targeting `tool_results` changes how some server types proxy traffic: |
| 126 | + |
| 127 | +{% table %} |
| 128 | +columns: |
| 129 | + - title: Server type |
| 130 | + key: type |
| 131 | + - title: What changes |
| 132 | + key: change |
| 133 | + - title: Effect |
| 134 | + key: effect |
| 135 | +rows: |
| 136 | + - type: "`passthrough-listener`" |
| 137 | + change: "{{site.ai_gateway}} holds a streamed `tools/call` response and releases it as one body." |
| 138 | + effect: "For an upstream that streams a response incrementally, time to first byte becomes time to last byte. An SSE response that contains one complete message isn't affected." |
| 139 | + - type: "`conversion-listener`" |
| 140 | + change: "{{site.ai_gateway}} disables single-pass conversion for converter tools that the AI MCP Server owns, and sends the call to the upstream as a separate request." |
| 141 | + effect: "Each call opens one additional outbound connection and doesn't use the load balancer, retries, upstream TLS or mTLS settings, the keepalive pool, or the configured timeouts." |
| 142 | +{% endtable %} |
| 143 | + |
| 144 | +Enabling `recover_redacted` has the same effect, because {{site.ai_gateway}} must hold the result to restore placeholders in it. |
| 145 | + |
| 146 | +These changes reverse when you remove `tool_results` from `sanitize_targets` and disable `recover_redacted`. |
| 147 | +A configuration that targets only `tool_arguments` without recovery doesn't change streaming or single-pass behavior. |
| 148 | +{{site.ai_gateway}} never buffers long-lived streams, such as `subscriptions/listen` and GET-initiated SSE. |
| 149 | + |
| 150 | +{:.warning} |
| 151 | +> Each sanitized call adds at least one round trip to the PII service. Load test the PII service with your largest and most deeply nested tool payloads before you enable the Policy in production. |
| 152 | +<!-- TODO: confirm the call pattern. The PRD describes one call per string value. The design doc and PR describe batched calls. --> |
| 153 | +
|
| 154 | +## Block instead of redact |
| 155 | + |
| 156 | +When `block_if_detected` is `true` and the PII service finds sensitive data, {{site.ai_gateway}} rejects the call instead of redacting it: |
| 157 | + |
| 158 | +* For `tool_arguments`, the agent receives a JSON-RPC error and the request doesn't reach the tool server. |
| 159 | +* For `tool_results`, {{site.ai_gateway}} replaces the result with a JSON-RPC error. |
| 160 | + |
| 161 | +The error uses the format and HTTP status that match the client's [MCP protocol revision](/ai-gateway/mcp-version-support/). |
| 162 | +<!-- TODO: confirm the error code and message --> |
| 163 | + |
| 164 | +## Recover redacted values |
| 165 | + |
| 166 | +When `recover_redacted` is `true`, the tool server receives placeholders instead of the original values. |
| 167 | +If the tool returns a placeholder in its result, {{site.ai_gateway}} restores the original value before it sends the result to the agent. |
| 168 | + |
| 169 | +<!-- TODO: PR #23501 shares its entity checks with ai-sanitizer, which rejects `recover_redacted: true` when the Policy sanitizes output. Confirm whether that rule applies to `tool_results`, and document the valid combinations. --> |
| 170 | + |
| 171 | +## Error handling |
| 172 | + |
| 173 | +The AI MCP Sanitizer Policy uses `stop_on_error` to decide what happens when the PII service is unreachable, returns a non-200 response, or returns a malformed response. |
| 174 | +<!-- TODO: confirm the default (`true` in the PRD) and the behavior of each value for both targets --> |
| 175 | +When the service returns fewer entries than {{site.ai_gateway}} sent, the behavior is still being decided. |
| 176 | +<!-- TODO: design doc open question 2 --> |
| 177 | + |
| 178 | +## Differences from the AI PII Sanitizer Policy |
| 179 | + |
| 180 | +The AI MCP Sanitizer Policy shares most settings with the AI PII Sanitizer Policy. |
| 181 | +The following table lists the settings that differ: |
| 182 | + |
| 183 | +{% table %} |
| 184 | +columns: |
| 185 | + - title: Setting |
| 186 | + key: setting |
| 187 | + - title: AI PII Sanitizer |
| 188 | + key: sanitizer |
| 189 | + - title: AI MCP Sanitizer |
| 190 | + key: mcp |
| 191 | +rows: |
| 192 | + - setting: Targeting |
| 193 | + sanitizer: "`sanitization_mode`: `INPUT`, `OUTPUT`, or `BOTH`" |
| 194 | + mcp: "`sanitize_targets`: `tool_arguments`, `tool_results`, or both" |
| 195 | + - setting: "`allow_all_conversation_history`" |
| 196 | + sanitizer: Supported |
| 197 | + mcp: Not available. Conversation history is an LLM concept. |
| 198 | + - setting: "`continue_on_detection`, `rejection_mode`" |
| 199 | + sanitizer: Supported |
| 200 | + mcp: Not available in the first release. <!-- TODO confirm --> |
| 201 | +{% endtable %} |
| 202 | + |
| 203 | +`INPUT`, `OUTPUT`, and `BOTH` are ambiguous on MCP traffic, because an AI MCP Server is both a server to the agent and a client of the tool server. |
| 204 | +`sanitize_targets` names the protocol location instead. |
| 205 | + |
| 206 | +## PII service |
| 207 | + |
| 208 | +The AI MCP Sanitizer Policy uses the same external PII service as the AI PII Sanitizer Policy. |
| 209 | +For the Docker images, the `anonymize` categories, redact modes, custom patterns, and HTTPS setup, see [AI PII Anonymizer service](/ai-gateway/policies/ai-sanitizer/#ai-pii-anonymizer-service). |
| 210 | +You run the PII service in your own environment. |
| 211 | + |
| 212 | +## Logging and analytics |
| 213 | + |
| 214 | +<!-- TODO: PRD and design doc say sanitization counts (identified, sanitized, duration, items) are added to the MCP statistics when logging statistics is enabled, and that `skip_logging_sanitized_items` omits the item details. PR #23501 moves MCP logging into an `emit-mcp-log` filter. Confirm the field names and add a link to the audit log reference. --> |
| 215 | + |
| 216 | +## Configuration notes |
| 217 | + |
| 218 | +* `anonymize` must contain at least one value. The default is `all_and_credentials`. |
| 219 | +* If `anonymize` includes `custom`, you must set `custom_patterns`. Each pattern needs a `name`, a `regex`, and a `score` between 0 and 1. |
| 220 | +* `sanitize_targets` must contain at least one target. |
| 221 | + |
| 222 | +<!-- TODO: Add entity examples and the scope and attachment model for AI MCP Server once the spec is available. --> |
0 commit comments