Skip to main content

Blueprint: Retail Return Agent

Fail-Closed PII Protection for Retail Return Messages

Agents processing customer returns often receive text messages containing emails, order IDs, and phone numbers. These payloads can contain high-density PII.

This blueprint demonstrates deterministic PII scanning and denial for retail return messages. A configured match is denied before the payload reaches the model. For mask-and-proceed behavior, use the Python SDK on Claude Code or Gemini CLI before forwarding.

Architecture

1. Master Policy Definition

{
"name": "retail-privacy-policy",
"priority": 7500,
"rules": [
{
"id": "mask-retail-pii",
"effect": "allow",
"principals": ["agent:return-bot"],
"actions": ["llm:generate"],
"resources": ["*"]
}
],
"content_policy": {
"enable_pii_detection": true,
"pii_action": "mask",
"blocked_patterns": ["\\bORD-\\d{4}-\\d{4}\\b"]
}
}

2. Implementation

Python Prototype

from openai import OpenAI

client = OpenAI(
api_key="ignored",
base_url="http://cz-gateway:8001/v1",
default_headers={"X-ControlZero-App": "returns"}
)

def process_return_request(message: str):
# This message contains an Email and a custom Order Pattern (ORD-xxxx-xxxx)
try:
response = client.chat.completions.create(
model="gpt-5.4-mini",
messages=[{"role": "user", "content": f"Customer Request: {message}"}]
)
return response.choices[0].message.content
except Exception as e:
return f"Governance Error: {e}"

# Scenario: Message with sensitive identifiers
raw_msg = "My email is user@example.com and my order number is ORD-1234-5678."
result = process_return_request(raw_msg)

# RESULT: The Gateway denies this request. For redacted continuation, use
# Python-SDK masking on Claude Code or Gemini CLI before forwarding.
print(f"Agent Response: {result}")

3. Validation Checklist

  • DLP Response: Verify that a PII match returns a denial rather than forwarding rewritten content.
  • Custom Patterns: Confirm that the ORD- regex pattern correctly triggers the denial.
  • Audit Trail: Verify audit findings contain no raw PII; do not expect request_payload_encrypted to hold the original payload.