How do I keep PII out of a vector database?

Mask PII with consistent tokens before you embed, and mask questions the same way. Vectors, chunk text and metadata then hold tokens, and real values return only to allowed readers.

SOC 2 Type II · ISO 27001 · HIPAA, BAA available

What is in your vector store?

  • Chunk textCustomer names
  • VectorCan be turned back into text
  • MetadataAn email in a filter field
  • Masked before embeddingtokens only
Trusted by regulated enterprises & agentic platforms
Inovalon
Automation Anywhere
Citrix
Bank Of Muscat Logo
Dell

The short answer

Do it before the embedding step. A vector is not anonymous: research has rebuilt most short inputs exactly from their embeddings, names included, and most stores keep the raw chunk text and metadata in the same row. Keep identifiers out of every copy.

01

Map every copy, and keep metadata minimal

Chunk text, vector, metadata, query logs, caches and evaluation sets are each a store you own. Metadata holds a source ID, a type and a tenant. No names, emails or raw text.

02

Detect PII before you chunk and embed

Names, emails and account numbers, and also combinations that point to one person: a birth year, an employer and a job title together.

03

Replace each value with a consistent token, not a blank label

[PERSON] makes every customer look the same. A token that stays the same for the same value, such as <PERSON>Xr4 Lp9Qw</PERSON>, keeps search by person working.

04

Mask the question the same way, and decide who sees real values at retrieval

The question finds the right chunks through the same tokens. Real values come back only for readers your policy allows.

05

Build the delete path

Carry the source ID through every copy, so an erasure request removes the chunk, the vector and the metadata in one lookup.

06

Where Protecto fits

Protecto’s agentic detection and classification engine masks text before your embedding step, with consistent tokens across 50+ entity types plus custom entities. It masks questions the same way and applies your access policy at retrieval. Your embedding model and vector database stay as they are.

Proof

Automation Anywhere uses Protecto to protect customer data across its AI platform, with each enterprise tenant’s own policy

Higher F1

Than AWS Comprehend and Microsoft Presidio in the independent UT Dallas / DataXpert benchmark

13M+

Long texts masked per day for a SaaS company

5,000+

Live enterprise tenants on Automation Anywhere, each with its own policy

One support ticket, from chunk to vector store

A telecom support team builds a RAG assistant over two years of tickets. The pipeline chunks each ticket, embeds it and writes it to a vector database.

The ticket below holds no card number or SSN, so a pattern filter finds nothing. But the name, email, phone, customer ID and the line “born 1961, head nurse at” one named hospital each point to one person. A typical pipeline stores that person three times in one row: in the raw text, in a metadata field, and in a vector built from both.

Switch the view to see the same ticket masked before embedding, then what happens when an agent asks about the customer.

Ticket 88213, from chunk to vector store

The chunk, as written (fictional)

Ticket 88213. Ingrid Solberg (ingrid.solberg@fjordmail.no, +47 412 55 908), customer ID NV-30418, born 1961, head nurse at Tromsø University Hospital. Charged twice for October roaming. Refund approved by supervisor.

The row the vector store keeps

{
"id": "chunk_88213_0",
"vector": [0.0213, -0.0871, 0.4410, ...],
"metadata": { "customer_email": "ingrid.solberg@fjordmail.no" },
"text": "Ticket 88213. Ingrid Solberg (ingrid.solberg@..."
}
Chunk textThe full ticket, readable by anyone who can query the store
MetadataHer email, sitting in a filter field
Vector, if invertedAn approximation of the sentence, name included

Nothing here is a card number or SSN, so a pattern filter passes it. Seven values still point to one person.

The double charge, the roaming and the refund stay readable in every view, so the masked chunk is still worth retrieving.

Where personal data lands in a RAG pipeline

Each stage writes a copy. Each copy needs masking or a retention period, and a delete path.

CopyWhat it holdsKeep PII out by
Chunk text in the vector storeThe source sentenceMasking before chunking and embedding
VectorA numeric form of the chunk that can be invertedEmbedding only masked text
MetadataFilter fields, often copied from the source recordAllowing only IDs and categories
Query and response logs, chat historyEvery question, including pasted customer detailsMasking the question; setting retention
Caches, observability tools, gatewaysFull prompts with retrieved chunks insideStoring the masked version; setting retention
Evaluation and fine-tuning setsSampled chunks and answersMasked or synthetic data only

An index shared by many users returns chunks by similarity, not by permission. Per-user policy at retrieval is the second control.

Why the vector store holds personal data

GDPR asks whether a person can be identified by means reasonably likely to be used. A vector does not pass that test on looks alone.

Inversion is a known method. An iterative method recovered 92% of 32-token inputs exactly from their embeddings, and recovered full names from clinical notes (Morris et al., EMNLP 2023). OWASP lists vector and embedding weaknesses as LLM08 in its 2025 Top 10 for LLM applications.

Tokenized text is pseudonymized, not anonymous. For you, holding the mapping, a masked index is still personal data (GDPR Article 4(5)). Masking lowers the risk in every copy and shrinks who sees real values. You still need a lawful basis, a retention period and a delete path.

For the full legal answer, including the EU Court of Justice ruling on pseudonymized data and what EDPB and ICO guidance says, read Are embeddings personal data under GDPR?

Not legal advice. Summarized from the sources linked, checked November 2026.

Ways to keep PII out of a vector database, compared

Each approach scored against what lands in the store, and whether search and the right readers still work.

ApproachVector can leak identifiersChunk text holds identifiersSearch by person still worksAllowed readers see real values
Embed raw text, restrict access to the databaseYesYesYesYes, and so does anyone else with access
Encrypt the store at restYes, once read by the appYes, once read by the appYesYes, and so does anyone else the app serves
Drop or hash identifiers before embeddingNoNoNoNo
Blank labels before embedding[PERSON], [EMAIL]NoNoBasic. Every person looks the sameNo
Mask only the model’s answerYesYesYesBasic. The index still holds everything
Protecto: consistent tokens before embedding, policy at retrievalNoNoYes. The same value gets the same token in every document and questionYes, by user, agent and task

Access control and encryption still matter. They protect the store; masking decides what is in it.

How Protecto keeps PII out of your vector store

Protecto masks text before it is embedded, masks questions the same way, and decides at retrieval who gets real values back.

  1. 1

    Detect before you embed

    Call Protecto on each document or chunk before your embedding step. The agentic detection and classification engine labels 50+ entity types across PII, PHI and PCI, plus custom entities such as your customer ID format, added in days.

  2. 2

    Replace with consistent tokens

    Each value becomes a tagged token, such as <PERSON>Xr4 Lp9Qw</PERSON>. The same value always gets the same token, in any document and any session, so related chunks stay linked.

  3. 3

    Embed and store only masked text

    Keep your embedding model and vector database. Vectors, chunk text and logs hold tokens. The mapping stays with Protecto, in your cloud or on-premises, not in the vector database.

  4. 4

    Mask the question, apply policy at retrieval

    A question about a person is masked with the same tokens, so it finds the right chunks. Protecto applies your policy for the user, the agent and the task: allowed readers see real values, the rest see tokens.

  5. 5

    Run at volume and keep the record

    Batch documents through the asynchronous API, or in pipelines through a Snowflake UDF, Databricks, Kafka or Spark. Protecto shows where sensitive data flows and logs each reveal.

What each part of the pipeline holds
  • Embedding modelMasked text only
  • Vector storeVectors, tokens and IDs
  • Query logs and cachesMasked questions
  • Allowed readersReal values, by policy
  • Your environmentReal values and the token mapping

Want the RAG stack run for you? Secure RAG in GPTGuard masks documents before indexing and applies your policy at retrieval. An insurance provider used it on claims notes that were masked, vectorized and stored for LLM search. Secure RAG →

Questions engineers ask about embeddings and PII

Is restricting access to the vector database enough?

No. Similarity search returns chunks by meaning, not by permission, so anyone who can query the index can surface another person’s data. Encryption at rest protects the disk, not what the application reads. Mask identifiers before embedding and apply policy at retrieval.

Often, yes. In Morris et al. (EMNLP 2023), an iterative method recovered 92% of 32-token inputs exactly and recovered full names from clinical notes. Longer chunks come back less exactly, but names and numbers can still be recovered.

No. A birth year, an employer and a job title together can point to one person, and so can an email or customer ID left in a metadata field. Detect identifiers and the combinations that act like them, and keep metadata to IDs and categories.

Yes, when the masking is consistent. Protecto gives the same value the same token in every document and every question, so a question about a person still finds that person’s chunks, and the rest of the sentence stays in place for meaning.

No. Tokenization is pseudonymization. For you, holding the mapping, the store is still personal data, and special category data such as health stays special category. Masking shrinks who can see real values and what an attacker can recover. It does not remove your duties.

Carry a source ID through every copy from the start. An erasure request then becomes a lookup that deletes the chunk text, the vector and the metadata, plus logs and caches under their own retention rules. Keep the path that answers access requests separate from the one that deletes.

No. You keep both. Protecto masks text before your embedding step, masks questions the same way, and applies policy at retrieval. If you want the RAG stack run for you instead, Secure RAG in GPTGuard handles chunking, embeddings and vector search on masked content.

Mask your index before embedding

Bring a sample of your documents. We will show what Protecto finds, what your vector store would hold, and what each reader gets back.

Cover of the PII/PHI identification benchmark study by UT Dallas and DataXpert
Benchmark study

PII/PHI detection, benchmarked by UT Dallas and DataXpert

A third-party study compares how accurately Protecto, Microsoft Presidio, and AWS Comprehend find personal and health data in unstructured text.

By submitting you agree to Protecto’s privacy policy.

New: run any AI model without exposing real values.
See how it works