Skip to main content

Your Embeddings Are PII: Inversion Attacks and the Right to Be Forgotten in the Vector Store

· 9 min read
Tian Pan
Software Engineer

Somewhere in your company's data classification policy, there is a table. Raw customer text — support tickets, medical notes, chat transcripts — sits in the "sensitive" row, wrapped in encryption requirements, access controls, and deletion SLAs. And then there is your vector store, holding embeddings of that exact text, classified as... nothing. Derived data. Anonymous math. Just floats.

That classification is wrong, and it is wrong in a way that is now experimentally demonstrated. Inversion attacks can reconstruct the original text from its embedding — in the best-studied setting, recovering 32-token inputs exactly in 92% of cases, including full names from clinical notes. If an attacker with your vectors can read your customers' words, your vectors inherit the sensitivity of those words. The regulators have started saying this out loud, and most retrieval architectures are not ready for what follows: a deletion request that has to reach every index, every snapshot, and every derived artifact — not just the row store.

Embeddings Were Never One-Way

The comfortable assumption was that embedding is a lossy hash: text goes in, semantics come out, and the mapping is irreversible in any practically meaningful sense. That assumption died with a family of techniques called embedding inversion.

The landmark result, vec2text, works by iterative refinement. Train a conditional language model that takes a target embedding and a text hypothesis, embeds the hypothesis, and uses the difference between the hypothesis embedding and the target embedding to propose a correction. Run that loop a few dozen times and the hypothesis converges — not to a paraphrase, but frequently to the exact original string. Against a production-grade embedding model, the method recovered 92% of 32-token inputs verbatim, with BLEU scores above 97. Applied to a corpus of clinical notes, it recovered patients' full names.

Follow-up work made the attack more practical, not less:

  • No query access needed. Transferable inversion attacks train a surrogate on a different embedding model and align the spaces, so an attacker holding a dump of your vectors doesn't need to call your embedding API at all.
  • It generalizes across domains. Reproducibility studies confirmed the effect holds across datasets and embedding models, not just the original paper's setup.
  • Longer texts leak too. Exact reconstruction degrades with length, but names, dates, diagnoses, account numbers — the entities that make text sensitive — are precisely the tokens inversion recovers most reliably, because they are the highest-information features the embedding must encode to be useful for retrieval.

The last point deserves emphasis, because it kills the most common rationalization. Embeddings are good for search because they preserve what is distinctive about a chunk. A chunk about "Jane Doe's stage-2 diagnosis on March 14" is retrievable precisely because that identifying information is encoded. Utility and leakage are the same property. You cannot have an embedding that retrieves well and inverts badly for free; every defense that adds noise or projects away dimensions pays for privacy with recall.

The Regulators Got There Before Your Architecture Did

If you were hoping to argue that embeddings are anonymous derived data, the European Data Protection Board closed that door in Opinion 28/2024. The Board's position: an AI model (and by direct extension, a store of learned representations) is only anonymous if the likelihood of extracting personal data from it is insignificant — and the assessment must explicitly account for attacks like membership inference and inversion. The threshold is high, case-by-case, and the burden of proof is on you.

Read that against the 92% exact-recovery number and the conclusion writes itself. A vector store built from personal text is a store of personal data. Not "arguably." Not "in an abundance of caution." As a straightforward application of the stated criteria: extraction is not just likely, it is a published technique with open-source tooling.

That has two consequences most teams haven't priced in:

  1. Every obligation that attaches to the source text attaches to the vectors. Access control, encryption at rest, breach notification if the index leaks, cross-border transfer restrictions, retention limits.
  2. Article 17 deletion requests are in scope. "The right to be forgotten" must reach the vector store with the same force it reaches your Postgres row — erasure that is verifiable and irreversible, not cosmetic.

The second one is where architectures quietly fail.

Why "Delete the Chunk, Keep the Vector" Fails Audit

Walk through what actually happens when a deletion request arrives at a typical RAG stack, and count the places the data survives:

  • Soft deletes in the index. HNSW-based systems — the default in most vector databases — typically handle deletion by flagging the vector's ID and skipping it at query time. The vector itself stays in the index file until compaction rebuilds it, which may be triggered rarely or never. Recent work on "ghost vectors" showed that soft-deleted embeddings remain physically present and reconstructible in HNSW index files. Suppression from query results is not erasure; guidance accompanying GDPR is explicit that erasure must be irreversible, and a flag is the definition of reversible.
  • Snapshots and backups. Your index is snapshotted for disaster recovery. The deleted vector lives in every snapshot taken before the deletion, on whatever retention schedule your infra team chose for reasons that had nothing to do with privacy.
  • Surrogate IDs that don't trace back. Chunks get content-hashed IDs or auto-increment keys. If you didn't store per-chunk provenance — which user, which source document — you can't even find the vectors you're obligated to delete. The request arrives with a user ID; your index speaks UUID.
  • Derived aggregates. Centroids for clustering, cached query results, summaries embedded from multi-document context that included the user's data. Each is a derived representation with its own lifecycle and no pointer back to the source.
  • The re-embedding cadence. Some teams rebuild their index from source on a schedule — weekly, quarterly. Deletion "works" by omission at the next rebuild, meaning the effective deletion SLA is the rebuild interval. If legal committed to 30 days and the rebuild is quarterly, that gap is a finding waiting for an auditor.

None of these is exotic. They are the default behavior of the most popular tools, which is exactly the problem: the compliant path requires deliberate architecture, and the non-compliant path is what you get by following the quickstart.

The Deletion-Propagation Architecture

The fix is not a heroic one-off purge script. It is treating deletion as an event that propagates through the same pipeline that ingestion does. The load-bearing components:

Provenance metadata on every vector. At write time, attach the subject identifier (user ID, patient ID, tenant ID) and source document reference to every chunk's metadata. This is the single highest-leverage decision in the whole design: deletion by user_id filter is a one-line operation if the metadata exists and an archaeology project if it doesn't. Retrofitting provenance onto an existing index means re-deriving lineage from source systems — budget weeks, not hours.

Tombstones through the indexing pipeline. A deletion request emits a tombstone event carrying the subject's ID set. Every consumer of embedded data subscribes: the primary vector index, replica indexes, caches, derived aggregate jobs. Each consumer acknowledges; a dead-letter queue catches the ones that fail, because "we think it propagated" does not survive an audit. Tombstones also gate retrieval in the window before physical erasure — a query-time filter is an acceptable interim measure as long as it is a step toward irreversible deletion, not a substitute for it.

Bounded compaction windows. Since HNSW soft-deletes leave the data physically present, schedule compaction (or index rebuild) at an interval shorter than your deletion SLA. If legal promised 30 days, compaction runs at most every two weeks. This converts "eventually erased" into a number you can put in a compliance document.

Backup expiry as the real deletion date. Purging backups per-record is usually impractical; the standard pattern is bounded backup retention plus a restore-time replay of tombstones — any snapshot restored must have the deletion log re-applied before serving traffic. Your true deletion guarantee is then max(compaction window, backup retention), and that number, not the row-delete timestamp, is what you should be reporting.

Aggregates rebuilt, not patched. Centroids and summaries that included deleted data get recomputed from surviving members. Track which aggregates consumed which sources — the same provenance discipline, one level up.

Teams that have published their approach — for example, the documented patterns for making managed RAG knowledge bases honor right-to-be-forgotten requests — converge on this same shape: identify by provenance, delete from source and index, verify, and handle the failure path explicitly.

The Classification Rule That Prevents the Next One

The architecture above fixes the vector store you have. The policy fix prevents the next five systems from repeating the mistake, and it fits in one sentence:

Derived representations inherit the sensitivity classification of the data that produced them.

Embeddings of medical notes are medical data. Embeddings of support chats are customer communications. The classification travels with the transformation — through embedding, summarization, clustering, and caching — and only drops when you can demonstrate, against current attack techniques, that recovery is genuinely insignificant. That is the EDPB's test, and it is a sound engineering test too: it forces the question "can this artifact be inverted?" at design time, when provenance metadata costs one extra field, instead of at request time, when its absence costs a quarter.

This rule is uncomfortable precisely because of where it points. It is not just the vector database: it is the embedding cache in Redis, the eval set sampled from production queries, the fine-tuning corpus distilled from user conversations, the analytics pipeline that clusters user feedback. Every one of them is downstream of personal data, and every one of them is currently classified, in most companies, as "internal — derived."

The inversion papers didn't create this exposure; they revealed it. The text was always in the vectors. The teams that internalize that now get to build deletion in as a pipeline feature. The ones that don't will meet it as an incident — a leaked index that turns out to be a leaked corpus, or a deletion request that turns into a discovery of how many places one user's words actually live.

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