Redacting the Name Doesn't Redact the Person
Here is a fragment of a Dutch insurance claim, after the open-source euRedact engine has run over it:
Verzekerde: mevr. A. Jansen, Lindelaan 14, [POSTAL_CODE] Utrecht
BSN [NATIONAL_ID], IBAN [BANK_ACCOUNT]
Verzekerde is sinds maart met burn-out thuis. Zij is de enige
nachtverpleegkundige op de afdeling oncologie van het ziekenhuis.Masked by the rules engineName and address, still in the clearHealth data and a quasi-identifier
The identifiers are gone: the citizen service number, the bank account and the postal code, each found by pattern and validated by checksum. Add a model that removes the name and the street, and most redaction pipelines would call this document done.
It isn't. The last two sentences say the insured has been off work with burn-out since March, which is health data. They also say she is the only night nurse on the hospital's oncology ward, so nobody on that ward needs her name to know who she is. The document still holds special-category data about a person who can be identified. Legally, it's in the same position as the original.
Identifiers are the part of personal data everyone looks for. The data the GDPR protects most strictly usually isn't an identifier at all.
What the GDPR protects hardest
Article 4(1) defines personal data as anything relating to a person who can be identified "directly or indirectly", including through "one or more factors specific to the physical, physiological, genetic, mental, economic, cultural or social identity" of that person. Recital 26 adds that identifiability is judged by "all the means reasonably likely to be used", and that pseudonymised data, which could still be attributed to someone with additional information, is still personal data. Removing the name doesn't take a document outside the GDPR if the rest of it still points to one person.
On top of that sit two stricter regimes.
Article 9 prohibits processing data revealing racial or ethnic origin, political opinions, religious or philosophical beliefs, trade-union membership, genetic data, biometric data used to uniquely identify someone, data concerning health, and data concerning sex life or sexual orientation, unless one of the narrow conditions in 9(2) applies.
Article 10 restricts data relating to criminal convictions and offences: it may be processed only under the control of official authority or where Union or member-state law authorises it.
The stakes match. Infringing Article 9 falls in the Article 83(5) fine tier: up to €20 million or 4% of worldwide turnover, whichever is higher. Processing either category at large scale requires an impact assessment under Article 35(3)(b). And a breach involving them is the kind most likely to be judged a high risk to the people affected, which under Article 34 means telling them directly.
It almost never looks like a diagnosis
Health data is broad. Article 4(15) includes data about "the provision of health care services", and Recital 35 adds "a number, symbol or particular assigned to a natural person to uniquely identify the natural person for health purposes". In real documents, health data looks like:
- absence: "on sick leave since March", "maternity leave", a Krankenschein. HR files are full of health data nobody filed under medical.
- a place: "the oncology ward", "the addiction clinic", "the fertility department".
- a medication or a purchase: "paracetamol 1g" attached to a person counts, prescription or not. In Lindenapotheke (C-21/23, 2024) the Court of Justice held that the details a customer enters to order pharmacy-only medicines online are health data, even without a prescription. It's enough that they allow conclusions about someone's health and that the medicine is probably for them.
Special categories can be revealed indirectly. In OT v Vyriausioji tarnybinės etikos komisija (C-184/20, Grand Chamber, 2022), publishing the name of an official's partner fell under Article 9 because it could reveal the official's sexual orientation by inference. "Requested halal meals", "shop steward for the night shift" and "signed the PvdA petition" contain no sensitive keyword, and each reveals an Article 9 category.
Criminal-offence data hides in ordinary files: a Führungszeugnis "ohne Eintragung" (a clean German record certificate) in an HR file, a traffic offence in a motor claim, "prior conviction for fraud" in a fraud investigator's notes.
And combinations identify people. Latanya Sweeney estimated from 1990 US census data that 87% of the population could be uniquely identified by ZIP code, gender and date of birth. Later re-analyses put the figure lower, but still at a majority. "The only night nurse on the oncology ward" works the same way: a role, a place and a shift, none of them identifying alone.
What euRedact covers
Our coverage catalogue gives this material its own types, separate from the identifiers:
| Type | What it covers |
|---|---|
MEDICAL_CONDITION |
Diagnoses, symptoms in clinical context, ICD-10 codes, medications and procedures attached to a person, negative test results for a named condition, disabilities, reproductive and sexual health, substance use, genetic information, sick and maternity leave |
SENSITIVE_ATTRIBUTE |
Ethnic origin, religious or philosophical belief, political opinion, sexual orientation, trade-union membership, criminal convictions and offences (Article 10), plus nationality and vulnerability disclosures such as being an asylum seeker or welfare recipient |
BIOMETRIC_REF |
Fingerprint, iris, face, voice and DNA template references, photo IDs |
HEALTH_INSURANCE |
Member and card numbers, the Recital 35 "number assigned for health purposes" |
HEALTHCARE_PROVIDER |
Clinician and provider registration numbers |
QUASI_IDENTIFIER |
The combining phrase that narrows a description down to one person |
FINANCIAL_AMOUNT |
Salaries, debts, settlements and benefits attached to a person |
JOB_TITLE, ORGANISATION_NAME |
Roles and affiliations that identify in combination |
Article 10 data has no type of its own, deliberately. It's reported as SENSITIVE_ATTRIBUTE. A placeholder like [CRIMINAL_CONVICTION] would tell anyone reading the redacted text exactly what used to be there. "Convicted of fraud in 2019" becomes a black box, and the label on the box is the disclosure. Folding it into a broader type means the mask itself doesn't leak.
One limit we'll state plainly: MEDICAL_CONDITION, SENSITIVE_ATTRIBUTE, BIOMETRIC_REF and QUASI_IDENTIFIER are detected only by the neural layer, euRedact Cloud, which is in closed alpha by invitation. The open-source engine emits only structured types, and none of them is a diagnosis.
Every category has its edge cases
Identifiers have formats and checksums. Sensitive data has neither, so no keyword list can find it: "met burn-out thuis" has no shape, and a match on "burn-out" would also flag "the burn-out of the old server". So every type comes with a written rulebook, our annotation canon, made up mostly of edge cases settled by dated rulings, some only days old. Almost all of them come back to one question: does this text state something about this person? A procedure, a product, a category or a general statement doesn't, however sensitive the vocabulary.
"Fever and a dry cough are typical of flu" in a patient leaflet describes a disease, while the same symptoms in someone's notes are health data. "Criminal-record check in progress" describes a procedure, while "casier judiciaire vierge" states a result, and a clean record counts as much as a conviction. "Facial recognition is enabled" describes a product, while "her enrolled face template" is her biometric. "No pork" fits a secular or dietary choice just as well, while "asks for kosher meals" reveals religious practice. Each label also has to be applied consistently, because a policy like "always redact MEDICAL_CONDITION, keep ORGANISATION_NAME for analytics" only works if the same text always gets the same label. The coverage page publishes those type boundaries.
That's also why the architecture is ordered the way it is. The rules engine removes every structured identifier on your side first, and only what's left goes to the model. That's data minimisation in the Article 5(1)(c) sense, applied to our own service: the layer that reads the sentences never sees the BSN.
Why it matters for the business
All of this can read like a list of reasons to keep sensitive documents away from AI. It's the opposite.
Plenty of the work AI is good at runs on documents like these. Claims handlers summarise medical reports. HR teams triage sick-leave correspondence. Case workers write similar notes again and again. Because those documents carry Article 9 data, a careful organisation often keeps exactly these processes out of its AI rollout, and the work stays manual.
Thorough redaction gives you a third option between "send it as-is and hope" and "do it by hand". A model doesn't need to know that the claimant is Mrs Jansen, or that her condition is burn-out, to check a claim against the policy terms or draft the reply. Replace the identifiers and the sensitive attributes with placeholders and the task is unchanged. The personal data just isn't in it anymore. Reversible tokenisation puts the real values back into the model's answer, on your side:
from euredact import redact, restore
result = redact(claim, countries=["NL"], tokenize=True)
reply = call_your_llm(result.redacted_text) # sees tokens, never the values
letter = restore(reply, result.tokens) # the real values, back in place
The mapping exists only in your process, for that one call, so the round trip doesn't create a new store of personal data.
This is where coverage decides everything. A pipeline that removes names but leaves the diagnosis hasn't reduced your Article 9 exposure. It has sent special-category data to a third party with a label saying it was redacted. Covering the sensitive types is what turns "we use AI on claims files" into something you can defend in an impact assessment: what the model receives, what it doesn't, and why.
No redaction makes the risk zero. What it changes is what's at stake: a model provider, a prompt log or a fine-tuning set that only ever held placeholders is a far smaller problem than one that held the original files.
The question to ask
Don't ask "does it remove names?" Ask what a supervisory authority would: once it's done, could someone still work out who this is about, and would they learn something Article 9 or Article 10 protects?
The open-source engine covers the identifiers today, locally and for free. If your documents carry the other kind (case notes, claims, HR files, medical correspondence), join the Cloud waitlist and tell us about the processes you'd want to use it for.