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

# Configure PII Scrubbing

> Set up data protection to automatically redact sensitive information from MCP responses.

Configure PII scrubbing to automatically redact sensitive information from MCP responses before they're logged or returned to clients.

## Prerequisites

<Tabs>
  <Tab title="Control Plane">
    * [Golf Control Plane account](https://app.golf.dev) with Admin role
    * MCP server registered in Control Plane
  </Tab>

  <Tab title="YAML">
    * Golf Gateway deployed in [Distributed mode](/gateway/guides/getting-started/deploy-hybrid-mode)
    * Familiarity with the [YAML schema](/gateway/reference/yaml-schema)
  </Tab>
</Tabs>

## Understanding the 3-layer policy hierarchy

PII scrubbing follows the same 3-layer hierarchy as other Golf Gateway policies:

| Layer            | Where Configured                    | Scope                       |
| ---------------- | ----------------------------------- | --------------------------- |
| **Organization** | Control Plane > Settings > Policies | All gateways & servers      |
| **Gateway**      | Control Plane > Gateway > Policies  | All servers on this gateway |
| **Server**       | Control Plane > Server > Policies   | Single MCP server           |

**Policy Merge Rules:**

* **Sensitive fields**: Combined from ALL layers (union)
* **Whitelist fields**: Combined from ALL layers (union)
* **Custom rules**: Combined from ALL layers (union)
* **Custom entities**: Combined from ALL layers (union)
* **Enabled flag**: True if ANY layer enables scrubbing

<Tip>
  Set organization-wide defaults for common PII types, then add server-specific rules for domain-specific data.
</Tip>

## Enable PII scrubbing

<Tabs>
  <Tab title="Control Plane">
    **Organization defaults:**

    1. Go to **Settings** > **Policies**
    2. Find the **PII Protection** section
    3. Enable **PII Scrubbing**
    4. Configure default sensitive field names
    5. Click **Save**

    **Gateway overrides:**

    1. Go to **Gateways** > select a gateway > **Policies**
    2. Find the **PII Protection** section
    3. Add gateway-specific sensitive fields
    4. Click **Save**

    **Server-level configuration:**

    1. Go to **MCP Servers** > select a server
    2. Open the **Policies** tab > **PII**
    3. Enable **PII Protection**
    4. Add custom sensitive field names
    5. Click **Save**
  </Tab>

  <Tab title="YAML">
    **Gateway-level defaults** (applies to all servers):

    ```yaml theme={null}
    gateway_policy:
      scrubbing:
        enabled: true
        sensitive_fields:
          - password
          - api_key
          - secret
        whitelist_fields:              # Fields that should NEVER be scrubbed
          - connection_id
          - session_id
          - cursor
          - tool_name
        recognizers:
          - entity_type: EMAIL_ADDRESS
            enabled: true
          - entity_type: CREDIT_CARD
            enabled: true
          - entity_type: URL
            enabled: false             # Disable URL scrubbing
    ```

    **Server-level overrides** (merged on top of gateway defaults):

    ```yaml theme={null}
    servers:
      - name: my-server
        url: http://localhost:3001
        security:
          enabled: true
          sensitive_fields:
            - api_key
            - password
          whitelist_fields:
            - report_id
          recognizers:
            - entity_type: EMAIL_ADDRESS
              enabled: true
              replacement: "[PII_EMAIL]"   # Custom replacement for this server
    ```
  </Tab>
</Tabs>

## Built-in PII detection

Golf Gateway detects many entity types by default. Common examples include:

| Entity Type      | Example                                     |
| ---------------- | ------------------------------------------- |
| `CREDIT_CARD`    | 4111-1111-1111-1111                         |
| `EMAIL_ADDRESS`  | [user@example.com](mailto:user@example.com) |
| `PHONE_NUMBER`   | (415) 555-1234                              |
| `US_SSN`         | 123-45-6789                                 |
| `IP_ADDRESS`     | 192.168.1.1                                 |
| `US_BANK_NUMBER` | 1234567890                                  |
| `URL`            | [https://example.com](https://example.com)  |
| `IBAN_CODE`      | DE89370400440532013000                      |

Additional supported types include `PERSON`, `LOCATION`, `ORGANIZATION` (via GLiNER), `US_DRIVER_LICENSE`, `US_PASSPORT`, `JWT_TOKEN`, and more.

## Add custom scrubbing rules

For patterns not covered by built-in detection, add custom rules:

<Tabs>
  <Tab title="Control Plane">
    1. Go to the appropriate level (Settings, Gateway, or Server > Policies)
    2. Find the **PII Protection** section
    3. Click **Add Custom Rule**
    4. Enter the regex pattern and select the masking method
    5. Click **Save**
  </Tab>

  <Tab title="YAML">
    Add custom rules at the **gateway level** (applies to all servers) or **server level** (per-server overrides):

    ```yaml theme={null}
    # Gateway-level custom rules
    gateway_policy:
      scrubbing:
        enabled: true
        custom_rules:
          - pattern: "sk-[a-zA-Z0-9]+"       # API keys
            method: mask

    # Server-level custom rules (merged with gateway rules)
    servers:
      - name: my-server
        url: http://localhost:3001
        security:
          enabled: true
          custom_rules:
            - pattern: "LINEAR-[A-Z]+-[0-9]+"  # Linear issue IDs
              method: mask
            - pattern: "TXN-\\d+"               # Transaction IDs
              method: replace
              replacement: "[TXN_ID]"
    ```
  </Tab>
</Tabs>

**Masking methods:**

| Method    | Behavior                                  | Example                          |
| --------- | ----------------------------------------- | -------------------------------- |
| `mask`    | Replace with `[REDACTED]`                 | `sk-abc123` → `[REDACTED]`       |
| `hash`    | Replace with SHA256 hash (first 16 chars) | `sk-abc123` → `a1b2c3d4e5f6g7h8` |
| `remove`  | Remove the value entirely                 | `sk-abc123` → \`\`               |
| `replace` | Replace with custom text                  | `sk-abc123` → `[API_KEY]`        |

## Configure per-server scrubbing

Different servers can have different scrubbing settings:

<Tabs>
  <Tab title="Control Plane">
    Configure each server individually through **MCP Servers** > server > **Policies** > **PII**.
  </Tab>

  <Tab title="YAML">
    ```yaml theme={null}
    servers:
      # Internal tools - minimal scrubbing
      - name: internal-tools
        url: http://localhost:3001
        security:
          enabled: true
          sensitive_fields: [password]
          whitelist_fields: [file_path, tool_name]

      # External API - comprehensive scrubbing
      - name: external-api
        url: http://localhost:3002
        security:
          enabled: true
          sensitive_fields: [api_key, bearer_token, secret, password]
          custom_rules:
            - pattern: "Bearer [a-zA-Z0-9\\-_]+"
              method: mask
          recognizers:
            - entity_type: EMAIL_ADDRESS
              enabled: true
              replacement: "[PII_EMAIL]"
            - entity_type: CREDIT_CARD
              enabled: true
              replacement: "[PII_CARD]"
    ```
  </Tab>
</Tabs>

## Verify scrubbing is active

1. In Admin Portal, go to **Logs**
2. Select a session and find a request containing PII
3. In the security pipeline, look for the **PII Scrubbed** step
4. Verify sensitive data shows entity-specific placeholders like `[EMAIL]`, `[SSN]`, or `[MASKED]`

## Fields never scrubbed

These fields are preserved for audit purposes and are never scrubbed regardless of configuration:

* `connection_id`, `session_id`, `correlation_id`
* `timestamp`, `event_type`, `method`
* `user.email`, `user.sub` (for compliance)

You can also configure additional fields to be excluded from scrubbing using `whitelist_fields` at the gateway or server level. This is useful for protecting operational data like file paths, tool names, or cursor tokens from accidental scrubbing.

## Troubleshooting

* **PII not being detected**: Verify scrubbing is enabled at all policy levels (org, gateway, server)
* **Custom pattern not matching**: Test your regex pattern - Golf Gateway uses Python regex syntax
* **Too much data being scrubbed**: Check if multiple layers are adding overlapping rules

## Related guides

* [Set Up Server RBAC](/gateway/guides/security/setup-server-rbac) - Access control
* [Golf Gateway Overview](/gateway/overview/golf-gateway#pii-scrubbing-policy) - Policy engine architecture
