trendingzones
← Back to the Intermediate level

AI & ML — ADVANCED

Cloud AI Privacy in Production: Masking Code & Architecture

The Intermediate level listed four privacy habits. Here’s the actual code behind the masking idea, why naive detection isn’t enough, and how each suggestion looks as a real production pattern.

The Quick Answer

Masking, in code, means detecting sensitive substrings with regular expressions and replacing them with numbered tokens, while keeping a local mapping table from each token back to its real value — that table is what makes the process reversible. Regex detection is simple but incomplete, which is exactly why production systems layer it into a shared proxy rather than trusting every caller to do it correctly by hand.

Reversible Masking, in Code

The core idea: detect sensitive substrings, replace each with a numbered placeholder, and remember the mapping so the response can be restored afterward.

import re

EMAIL_PATTERN = r"[\w.+-]+@[\w-]+\.[a-zA-Z]{2,}"
PHONE_PATTERN = r"\b\d{3}[-.]?\d{3}[-.]?\d{4}\b"
SSN_PATTERN = r"\b\d{3}-\d{2}-\d{4}\b"
NAME_PATTERN = r"\b[A-Z][a-z]+ [A-Z][a-z]+\b"  # crude: capitalized two-word sequence

def mask_and_map(text):
    mapping = {}
    counters = {"PERSON": 0, "EMAIL": 0, "PHONE": 0, "SSN": 0}

    def replace(pattern, label):
        nonlocal text
        def _sub(match):
            counters[label] += 1
            token = f"[{label}_{counters[label]}]"
            mapping[token] = match.group(0)
            return token
        text = re.sub(pattern, _sub, text)

    replace(SSN_PATTERN, "SSN")
    replace(EMAIL_PATTERN, "EMAIL")
    replace(PHONE_PATTERN, "PHONE")
    replace(NAME_PATTERN, "PERSON")
    return text, mapping

def unmask(text, mapping):
    for token, original in mapping.items():
        text = text.replace(token, original)
    return text

original = "Rahul Sharma (rahul.sharma@example.com, 555-123-4567, SSN 123-45-6789) filed a complaint."
masked, mapping = mask_and_map(original)
print(masked)
# [PERSON_1] ([EMAIL_1], [PHONE_1], SSN [SSN_1]) filed a complaint.

model_response = "I have logged the complaint from [PERSON_1] and will follow up via [EMAIL_1] or [PHONE_1]."
print(unmask(model_response, mapping))
# I have logged the complaint from Rahul Sharma and will follow up via rahul.sharma@example.com or 555-123-4567.

Only masked — the version with placeholder tokens — ever reaches the cloud model. The mapping dictionary that makes restoration possible never leaves the local machine.

See the full round trip yourself: masking, a simulated cloud response referring to the masked tokens, and the restored result.

Why Regex Detection Isn’t Enough

The name pattern above — a capitalized word followed by another capitalized word — catches “Rahul Sharma” but misses plenty of real names in ordinary text:

import re
NAME_PATTERN = r"\b[A-Z][a-z]+ [A-Z][a-z]+\b"

tricky = "sarah mentioned that Dr. OBrien reviewed the file, and so did dave."
print(re.findall(NAME_PATTERN, tricky))
# []  -- lowercase "sarah" and "dave", and "OBrien" (no space) all slip through

This is the real limit of the pattern-matching approach: it catches formatted, predictable data well (emails, phone numbers, SSNs all have a fixed shape), but names and other free-form personal information don’t follow one consistent pattern. Production systems that need thorough coverage typically add a dedicated named-entity recognition (NER) model on top of regex, not instead of it — regex for structured data, NER for the messier, context-dependent cases regex can’t reliably catch.

Elaborating Every Intermediate Suggestion

Source: Anthropic Privacy Center, “Zero Data Retention Agreements”

Fun Fact

Even under a zero-data-retention agreement, Anthropic’s policy still retains one thing: the output of its safety classifiers, specifically to enforce its usage policy — zero retention isn’t the same as zero visibility into whether a request violated policy.

Test Yourself

In the reversible pseudonymization pattern, what actually gets sent to the cloud model?

Why does regex-based PII detection sometimes miss real names?

What is the main trade-off of masking sensitive data before sending it to a cloud model?

What does a self-hosted masking proxy architecture accomplish?