Skip to main content

The PII Redactor That Scrubbed the User's Question and Left the Prompt Cache Untouched

· 11 min read
Tian Pan
Software Engineer

A customer audit finds eleven months of verbatim user PII sitting in a Redis cluster nobody on the residency team knew existed. No system was compromised. No attacker got in. The data was written there on purpose, by a service the inference team built and named "prompt cache," as a performance optimization. The redactor on the analytics path worked perfectly the entire time. The redactor was simply not on this path.

The breach is real anyway. Under GDPR, retention beyond the contracted thirty days is enough; the data does not need to have leaked to trigger Article 33 notification obligations. The residency team's inventory listed every log, every warehouse, every queue — and missed the cache because the cache was on the inference team's side of the org chart. The privacy boundary that everyone trusted ran straight down the analytics pipeline and stopped at the wall where the LLM stack began.

This is the canonical failure mode of two-path architectures: a sanitization layer that protects one path is read as protecting both, because the diagram on the architecture wall draws a single envelope around "data goes into the system." The envelope is a fiction. Inbound user data fans out the moment it hits the edge, and every downstream consumer that touches the raw bytes inherits a retention obligation it almost certainly does not know about.

The Redactor Was Doing Exactly What It Was Asked

The redaction layer in the standard architecture is a Presidio or AWS Comprehend or in-house NER step that intercepts inbound messages, replaces names, emails, phone numbers, account numbers with typed placeholders, and forwards the redacted version to whatever needs to see it. The forwarding target is the part teams underspecify. In most stacks the redactor sits on the path to the analytics warehouse and the log pipeline, because those are the surfaces the privacy review focused on a year ago when the GDPR program got serious.

The LLM-facing path is deliberately not redacted, and there is a good reason. A support agent that gets <PERSON_1> instead of the customer's name produces a worse answer; a billing agent that gets <EMAIL_REDACTED> cannot look up the account. The model needs the raw values to do its job. Splitting the path is the correct architectural decision; the bug is in what happens to the raw values after the model is done with them.

The provider's SDK takes the raw request and signs it. Your gateway logs the signed request with the body excluded — good. The provider returns a response. Somewhere in this round trip, on your side of the wire, a prompt cache stores the request keyed by a content hash, so that the next semantically identical request can be served without paying the provider again. The cache is on your infrastructure. The cache's TTL was set by the engineer who deployed Redis. The cache's eviction policy is LRU, sized by memory budget, not by retention requirement. Nobody told the cache what GDPR says.

Prompt Caches Are Data Stores, Whether or Not You Named Them That

The mental model that breaks the privacy boundary is treating a cache as ephemeral. Caches feel ephemeral because they evict, because they are sized in memory, because the code calls them caches. None of that is what GDPR cares about. GDPR cares about whether the personal data of an EU resident is held longer than the contract allows, regardless of why and regardless of the storage tier.

The actual retention behavior of a typical prompt cache is not ephemeral. A hot key in a high-traffic shared system can sit in Redis for months — LRU evicts the cold tail, not the warm core. A cache shared across tenants for common system prompts develops a long-tail of warm entries because the variance is on the user-message side, which means the user-message content (PII included) is exactly the part of the request that determines the cache key and therefore the retention. The same engineering decisions that produce a good cache hit rate produce a long retention window for the data that varies request to request, which is the data the privacy team cares about.

Major providers have moved hard on this. Anthropic's hosted prompt cache documents a 5-minute default TTL and a 1-hour optional tier, and explicitly states the cache is held in memory and not persisted at rest. OpenAI's hosted cache is similar at 5–10 minutes baseline, up to 24 hours under extended retention, isolated at the organization level. Both providers also offer zero-data-retention arrangements where the cache feature is excluded from any persistence. Those are the provider-side caches. The cache the residency team missed in the incident above is the one the application team built in front of the provider, and that one runs on whatever TTL the application team set.

Two Caches, Two Risks

The architectural distinction worth naming clearly:

  • Provider-side cache lives on the LLM vendor's infrastructure. You influenced it (cache breakpoints, optional retention tiers), but you do not configure its TTL or evict its entries. Its retention behavior is whatever the vendor contract says it is. For Anthropic, OpenAI, and Google, that is documented and bounded.
  • Application-side cache lives on your infrastructure, in front of the provider. You built it to skip the provider call entirely on a content-hash match, often for cost rather than latency. Its retention behavior is whatever your team configured, and "whatever your team configured" is almost always "Redis defaults plus an LRU eviction policy" because the engineer who shipped the cache was optimizing hit rate, not auditing data flows.

The first one is on the vendor's data processing addendum. The second one is on your team's risk register, except it usually is not, because the team that built the cache reports to the inference org and the team that maintains the data inventory reports to the privacy org, and the two orgs have a meeting on Wednesdays where neither group volunteers a piece of infrastructure the other group has never asked about.

Loading…
References:Let's stay in touch and Follow me for more thoughts and updates