How do I stop AI agents from seeing customer PII?
Updated · DBShifts
Short answer
Find the sensitive columns first, then mask them on the server before results leave your infrastructure, so neither the agent nor the AI provider receives raw values. Masking must also block filtering, grouping and joining on masked columns, or an agent can reconstruct a value from row counts without ever reading it.
Key facts
- An instruction in a prompt such as 'do not reveal emails' is not a privacy control.
- Server-side masking means the model provider never receives the raw value.
- A masked column that can still be filtered leaks through row counts, one guess at a time.
- Deterministic masking keeps joins and uniqueness working while hiding the real value.
- A minimum group size stops an aggregate from describing a single person.
Step one: find the personal data
Scan sampled values, not just column names: a column called notes2 can hold email addresses. Validate what you can — a 16-digit number is only a card number if it passes the Luhn check — so the scan does not drown you in false positives.
Step two: mask on the server
Masking has to happen before data leaves your infrastructure. Once a raw value is in a model's context it is in the provider's request logs and possibly in the agent's output, and no later step can take it back.
Step three: close the side channels
Agents do not need to read a column to learn it. Filtering on it turns row counts into an oracle; grouping by it lists the distinct values; tiny groups in an aggregate single out individuals. Refuse all three on masked columns.
Checklist
- 1
Scan sampled values and column names for personal data on connect
- 2
Mask matching columns by default for every agent
- 3
Refuse filters, group-bys and joins on masked columns
- 4
Set a minimum group size for aggregates
- 5
Never give agents unmask rights; grant unmasking to named people only
- 6
Review free-text columns by hand — whole-value pattern scans won't catch an email buried inside a sentence
Common mistakes
Masking only the SELECT list
If the column is still usable in a WHERE clause, the mask is decorative: counts of matching rows reveal the value.
Unmask rights for agents
An agent that can unmask will, as soon as a prompt asks it to. Keep unmasking for named people with a reason recorded.
Assuming free text is clean
Notes, messages and descriptions often contain personal data inside longer text. Treat those columns as sensitive or exclude them.
How DBShifts does it
- On connect, DBShifts scans sampled values with deterministic patterns — email, phone, card numbers with Luhn validation, SSN, Aadhaar, PAN, passport and IP address — plus column-name heuristics.
- Detected columns are masked on the server before results reach the agent or the model provider.
- Agents cannot filter, group or join on a masked column, and agents never hold unmask rights.
- Aggregates can enforce a minimum group size, and an exposure cap limits what share of a table one token may ever see.
- No AI is involved: detection is pattern matching and masking is deterministic, so joins and unique keys still work.
Questions people also ask
Does the AI do the masking?
It should not. Masking decided by a model can change between runs and cannot be audited. In DBShifts detection is pattern-based and masking is deterministic.
Can an analyst still see the real values?
Yes, through an explicit, expiring grant to a named person, recorded with a reason. Agents never receive one.
Related questions
Give AI agents data access you can defend
Scoped tokens, PII masked on the server, every request audited. Free to start.
Start free18 answers in this series. See all.