AI & ML / Guardrails & safety / 03_pii_privacy_and_compliance.md

PII, privacy and the EU AI Act

Updated 8 interview angles 12 min read source
On this page11
  1. The mechanism: an LLM pipeline is a copying machine
  2. An embedding is not anonymisation
  3. Redaction, and how much it buys
  4. Data residency
  5. The EU AI Act
  6. Other regimes
  7. Where it breaks in production
  8. What to build
  9. The trade not taken
  10. Related
  11. Interview angle

PII, privacy and the EU AI Act

Article.

Verified 2026-08

Verified 2026-08.

A user asks you to delete their data. In a normal service that is a DELETE across a handful of tables. In an LLM system, name every place their data came to rest and say which of those you can actually honour — that question sorts people who have run one of these in production from people who have read about compliance.

Regulatory timelines shift; the dates below were re-checked 2026-08 and are worth re-verifying before you rely on specifics.

The mechanism: an LLM pipeline is a copying machine

A conventional request reads data and returns it. An LLM request copies it — a prompt is a copy, an embedding is a derived copy, a checkpoint is a copy, a cache entry is a copy, and a log line is a copy.

text
   user text
      |
      +--> provider API      (their retention window)
      +--> your request log  (often verbatim by default)
      +--> trace / span      (a second vendor)
      +--> agent checkpoint  (full message history)
      +--> semantic cache    (keyed by meaning)
      +--> vector index      (derived, still personal)
      +--> fine-tuning set   (no delete path)
      \--> model output ---> wherever that gets written

Each arrow is a new controller obligation and a new place a deletion request has to reach. Most of them were created by a library default rather than by a decision, which is why the honest answer to “where is this user’s data” is usually longer than the architecture diagram suggests.

Which copies can be deleted

Where Deletable?
Your database yes, ordinary delete
Your logs and traces yes, if retention is bounded
Agent checkpoints yes, once you know they exist
Semantic caches yes, if keyed so you can find them
Vector index yes, if chunks carry a subject id
Provider-side logs only via their retention terms
Fine-tuned weights no

The two rows people miss are checkpoints and fine-tuning data. A durable agent persists conversation history to a database, which makes it a personal data store subject to the same rules as any other — and nobody put it on the data map because the framework created it.

Fine-tuning is worse: personal data in the training set is in the weights, and there is no operation that removes it short of retraining from a cleaned corpus. A deletion request against a fine-tuned model is unsatisfiable, which is the actual reason not to fine-tune on personal data — not cost, not quality.

An embedding is not anonymisation

The most common wrong assumption in this area, and worth being able to refute precisely.

“We only store vectors, not text” is offered as a privacy control constantly. It is not one. Embedding inversion research — the vec2text line of work from 2023 onward — reconstructs the source text from its embedding with high fidelity, recovering short passages exactly a large fraction of the time when the attacker knows the embedding model.

python
# What people think they stored          What it actually is
[0.021, -0.118, 0.334, ...]              "Jane Okafor, NHS no. 4432..."

What follows from that

The consequences are all practical:

  • A vector index holding embeddings of personal data is a personal data store. It needs the same access control, retention policy and deletion path as the source table.
  • Deletion must reach it. Store a subject reference on every chunk at ingest time, because reconstructing which of four million vectors belong to one person afterwards is not a thing you can do.
  • Redact before embedding, not after retrieval. Redaction applied on the way out leaves the identifiers sitting in the index.
python
class Chunk(BaseModel):
    id: str
    doc_id: str
    subject_ref: str | None   # who this is about; the delete key
    text: str
    embedding: list[float]

async def forget(subject_ref: str) -> None:
    await index.delete(filter={"subject_ref": subject_ref})
    await checkpoints.delete_where(subject_ref=subject_ref)
    await cache.invalidate_by_subject(subject_ref)
    await docs.delete_where(subject_ref=subject_ref)

Writing that function early is the cheap move. Writing it after a regulator asks means discovering which stores have no key to delete by.

Redaction, and how much it buys

python
# "John Smith called about account 4432" ->
# "[PERSON_1] called about account [ACCOUNT_1]"
redacted, mapping = redact_pii(text)
response = await llm(redacted)
final = restore(response, mapping)

Placeholder-and-restore keeps raw identifiers out of the provider’s context and logs while preserving enough structure for the model to be useful. Detection uses Presidio, spaCy NER or a small classifier.

All of them are recall-limited, so treat this as risk reduction rather than a control — the same distinction as prompt injection. Unusual names, informal references, transliterations and domain-specific identifiers are exactly what NER misses, and a miss is silent.

And redaction does nothing about quasi-identifiers. “The night-shift nurse at the Leeds site who transferred in March” names nobody and identifies one person. Nothing in a PII detector will flag it.

Logging

Do not log prompts and responses verbatim by default. Log token counts, latency, cost, model version and a trace id. Log content only when sampled, redacted, and on a short retention.

The default in most LLM observability tooling is the opposite, and it silently makes your tracing vendor a processor of everything your users typed.

Data residency

If personal data must stay in a region, use a deployment that guarantees it — a region-pinned managed endpoint rather than a public API. This is usually the actual reason enterprises pick a cloud-hosted model over a direct provider API, and it is a better answer than any feature comparison. See Azure for an AWS-shaped brain.

Check the provider’s terms on training from your inputs — business tiers generally exclude it, consumer tiers may not — and on retention. Providers typically keep API inputs for an abuse-monitoring window measured in weeks; zero-retention arrangements exist and generally have to be requested rather than being the default.

The EU AI Act

Risk-tiered regulation with extraterritorial reach: it applies if the system is used in the EU, wherever you are.

Tier Examples Obligation
Prohibited social scoring, manipulation banned
High-risk employment, credit, essential services conformity assessment
Limited risk chatbots, generative content transparency
Minimal spam filters, most tooling none

What applies right now

The timeline was amended on 16 June 2026, which is the detail separating a current answer from a stale one:

  • Most high-risk obligations were delayed. Standalone high-risk systems (Annex III) moved from August 2026 to December 2027; product-embedded high-risk systems (Annex I) moved to August 2028.
  • Article 50 transparency duties were NOT delayed and took effect 2 August 2026.
  • GPAI enforcement powers and the penalty regime also activated 2 August 2026. The first year was compliance on paper without penalty exposure; that has changed.

So the practical position: transparency obligations are live, penalties are live, and the heavy high-risk conformity work has more runway than originally scheduled.

Article 50, which is most people

  1. Disclose that users are interacting with an AI, unless it is obvious.
  2. Mark AI-generated content machine-readably.
  3. Label deepfakes and synthetic media.

Pre-existing systems have until 2 December 2026 for the machine-readable marking duty specifically. In practice: a visible “AI assistant” label, provenance metadata on generated media, and disclosure in the UI rather than buried in terms.

If you are high-risk

Risk management, data governance, technical documentation, automatic logging of operation, human oversight, accuracy and robustness measures, and conformity assessment before market.

The engineering implication is that audit logging and human oversight stop being nice-to-haves. If the system decides anything about employment, credit or access to essential services, you must be able to show a human could meaningfully intervene, and hold records of what it did.

Other regimes

  • GDPR applies independently. Automated decisions with legal or similarly significant effects trigger Article 22 rights, including meaningful information about the logic involved — a real argument for interpretable models in those domains.
  • Sector rules — HIPAA, PCI-DSS, financial regulation — apply as they always did. An LLM in the flow exempts nothing.
  • Copyright on training data and outputs remains contested. Note it as a risk; do not claim certainty.

Where it breaks in production

The delete that missed three stores

The subject row is gone, the vector index still has forty chunks, the agent checkpoint still has the full transcript, and the semantic cache still returns their data to the next person who asks a similar question.

The deletion path has to be written as one function that fans out, tested, and extended whenever a new store appears. A per-service delete implemented by whoever added that service is how you end up with three of five.

The semantic cache that crosses tenants

A cache keyed on embedding similarity rather than on identity will happily serve tenant A’s cached answer to tenant B, because the questions were similar. It is a correctness bug and a data breach in the same line of code.

python
key = (tenant_id, user_id, embed(question))   # identity FIRST, then similarity

Scope every cache by tenant, and by user wherever the answer depends on who asked.

Logs in a second vendor

Prompts are redacted before the provider call and the tracing SDK captures the unredacted span attributes anyway. Now the observability vendor holds everything and nobody listed them as a processor.

Redact at the point of capture, not at the point of send, and audit what the tracing integration records by default.

The model repeating what you gave it

Redaction on the way in does nothing if the response is written somewhere durable and the model reconstructed an identifier from context. Anything an LLM writes into a store you keep is data you now hold.

The retention flag applied to one endpoint

Zero-retention is negotiated for the chat endpoint; the embeddings endpoint, the batch API and the evaluation tooling each go through a different path with the default. Enumerate every egress, not every feature.

What to build

Requirement Implementation
Disclosure visible AI labelling in the UI
Content marking provenance metadata on generated media
Audit trail immutable record of inputs, model, decision
Human oversight approval gates, override, escalation
Data governance retention, deletion path, residency
Explainability log retrieved context and reasoning traces

The audit trail is the one to mention, because it is simultaneously a compliance answer and ordinary good engineering:

python
@dataclass(frozen=True)
class DecisionRecord:
    decision_id: str
    subject_ref: str          # pseudonymous, not a name
    model: str                # pinned version, never an alias
    prompt_version: str
    context_ids: list[str]    # what was retrieved, by id
    outcome: str
    reviewed_by: str | None   # the human oversight, as evidence
    at: datetime

Note what it does not contain: the prompt text, the retrieved passages, or the subject’s name. It stores references, so the record itself is not another copy of the personal data.

reviewed_by is what turns “a human could intervene” from a claim into evidence, and pinning model to a version rather than an alias is what lets you answer “what decided this” a year and three provider upgrades later.

The trade not taken

The strongest privacy control is not sending the data at all.

Pseudonymise at the boundary — replace identities with opaque references before anything reaches the pipeline, and resolve them only in the application layer that already had the right to see them. The model works on structure and content, which is usually what it needed; the identifiers never enter a prompt, a log, an index or a cache, and the deletion story collapses back to one table.

The alternative people reach for instead is self-hosting an open-weight model, which removes the provider from the picture. That is a real option and it is not the same as removing the problem: your logs, checkpoints, caches and vector index are all still there, and now you own the infrastructure too. It solves residency and third-party processing; it does nothing about the copying machine.

Deciding which of those you need is the actual design question, and the answer turns on whether the risk is who else holds it or how many places you hold it.

Interview angle 8

  • “A user requests erasure. Can you comply?” — for the database, logs, checkpoints, caches and vector index, yes, provided each store carries a subject reference you can delete by. For anything fine-tuned into weights, no, and there is no operation that fixes that short of retraining — which is the real reason not to fine-tune on personal data.
    • Follow-up: “Which of those stores do teams usually miss?” — agent checkpoints and the vector index. The checkpoint was created by the framework and never made it onto the data map, and the index is assumed to be anonymous because it holds numbers.
  • “Is an embedding personal data?” — yes, where the source was. Embedding inversion reconstructs the original text with high fidelity when the attacker knows the model, so “we only store vectors” is not a privacy control. Redact before embedding, and put the delete key on the chunk.
  • “Where does PII leak in an LLM system?” — the pipeline is a copying machine: the provider call, their retention window, your logs, the tracing vendor’s spans, agent checkpoints, the semantic cache, the vector index, fine-tuning data, and whatever the output gets written into. Most of those copies came from a library default rather than a decision.
  • “How good is PII redaction?” — recall-limited, so risk reduction rather than a control. NER misses unusual names, informal references and domain-specific identifiers, and it cannot touch quasi-identifiers at all — “the night-shift nurse who transferred in March” names nobody and identifies one person.

On the regulation

  • “What does the EU AI Act require of a chatbot?” — Article 50 transparency: disclose it is an AI, mark generated content machine-readably, label deepfakes. Those took effect 2 August 2026 and were explicitly not delayed.
    • Follow-up: “Wasn’t the whole thing delayed?” — partly. The June 2026 amendments moved standalone high-risk obligations to December 2027 and product-embedded ones to August 2028. Transparency duties, GPAI enforcement powers and the penalty regime all still started on 2 August 2026.
  • “How do you use an LLM with data that cannot leave the region?” — a region-pinned managed deployment rather than a public endpoint, plus checking the terms on training from inputs and on retention. That requirement is usually why enterprises choose a cloud-hosted model in the first place.
  • “What changes if the system is high-risk?” — risk management, data governance, technical documentation, automatic operational logging, demonstrable human oversight and conformity assessment. Engineering-wise: audit logging and a meaningful human override become mandatory, and the record has to pin the model version to be worth anything later.
  • “What would you do instead of all this?” — pseudonymise at the boundary so identities never enter the pipeline. The model usually needed the structure, not the names, and the deletion story collapses back to one table.