Redaction Pipelines for DSAR Exports: Releasing One Subject’s Data Without Another’s

The compliance failure in a subject access response is almost never that you disclosed too little. It is that you disclosed someone else’s data along with the requester’s.

Most of the effort that goes into data subject access requests is spent on discovery: finding every mailbox, ticketing system, CRM record and shared drive where the requester’s personal data might live. That is the visible, laborious part, and it is where the tooling budget usually goes. But the discovery problem is not the one that gets firms sanctioned. The one that does is the moment a colleague drops a bundle of emails and documents into an export and ships it, and buried in those emails are the names, addresses, medical details and grievances of other people who never asked for anything. You have answered one person’s rights request by breaching another person’s.

What the right of access actually stops short of

Article 15 of the GDPR gives a data subject the right to obtain a copy of their personal data. It is a broad right, and the instinct of a nervous compliance team is to over-comply: when in doubt, hand it over. That instinct is wrong, because the right has an explicit limit. Article 15(4) states that the right to obtain a copy “shall not adversely affect the rights and freedoms of others”. Recital 63 makes the same point in the reasoning: the right of access should not adversely affect the rights or freedoms of others, including the personal data of other individuals. The UK GDPR carries the same limit, and the ICO’s guidance frames it as a balancing exercise — you disclose third-party data only where the other person has consented or where it is reasonable in all the circumstances to do so without their consent.

Free · 4 minutes

Do you know where AI is already being used in your business — and what it can see?

Fourteen questions on shadow AI, data exposure, oversight, and governance debt — the gap between how fast AI is arriving and how much control you have over it. Banded finding on screen, full sheet by email.

The engineering consequence of that is specific. A DSAR export is not a dump of everything that mentions the requester. It is a filtered artefact in which the requester’s own personal data survives and other people’s personal data is removed or obscured, with a defensible record of what was withheld and why. That is a redaction pipeline, and it is a different problem from discovery.

Why manual redaction fails at volume

The traditional answer is a paralegal with a black marker, digital or otherwise, reading every page. That works for one request against fifty documents. It collapses at any real volume, and it collapses in a particular way: reviewer fatigue. The two-hundredth email in a thread gets the same three seconds of attention as the second, a co-worker’s home address in a forwarded signature block slips through, and the miss is invisible until the affected person complains. Manual review does not fail loudly. It fails silently, one overlooked identifier at a time, and you find out when a supervisory authority does.

Automating the first pass changes the economics. A machine does not get bored on page two hundred. It will not catch everything — no named-entity detector does — but it catches the routine, high-frequency identifiers consistently, and it lets human review concentrate on the genuine edge cases rather than on re-reading signature blocks. The goal is not to remove the human. It is to stop wasting the human on the mechanical part.

The trap in off-the-shelf PII scrubbing

Here is the mistake most teams make when they reach for a PII detection library. These tools are built to remove all detected personal data — that is their default purpose, whether the use case is anonymising a training set or scrubbing logs. Point one at a DSAR bundle unchanged and it will dutifully redact the requester’s own name, email and address, which are precisely the things the request exists to disclose. You end up with a compliant-looking export that satisfies nobody, because the one person entitled to the data has had theirs blacked out too.

The correct pattern inverts the default. You build an allow-list of the requester’s known identifiers — the names, email addresses, account numbers and phone numbers you already hold for them — and you redact every detected entity except those. Third-party PII goes; the subject’s own data stays. This is a classification-and-redaction problem, the same shape as the one behind the Data Act trade-secret carve-out, where the question is likewise not “is this personal data” but “whose, and is it releasable”.

A redaction step that keeps the subject’s data

Microsoft’s Presidio is a reasonable open-source starting point: an analyser that detects entities and an anonymiser that transforms them. The step below detects PII in a document, then suppresses redaction of anything matching the requester’s own identifiers before writing the redacted text out.

from presidio_analyzer import AnalyzerEngine
from presidio_anonymizer import AnonymizerEngine
from presidio_anonymizer.entities import OperatorConfig

analyzer = AnalyzerEngine()
anonymizer = AnonymizerEngine()

# Identifiers we already hold for the requesting data subject.
# Anything matching these must survive redaction.
SUBJECT_IDENTIFIERS = {
    "amelia okonkwo",
    "a.okonkwo@example.com",
    "acct-40192",
}

def redact_third_party(text: str, doc_id: str):
    """Redact third-party PII, preserving the requester's own data.
    Returns the scrubbed text and a withholding log for the audit trail."""
    results = analyzer.analyze(text=text, language="en")

    to_redact, withheld = [], []
    for r in results:
        span = text[r.start:r.end]
        if span.strip().lower() in SUBJECT_IDENTIFIERS:
            continue  # the subject's own data — leave it in
        to_redact.append(r)
        withheld.append({
            "doc_id": doc_id,
            "entity_type": r.entity_type,
            "start": r.start,
            "end": r.end,
            "score": round(r.score, 3),
            "basis": "third-party personal data, Art. 15(4)",
        })

    scrubbed = anonymizer.anonymize(
        text=text,
        analyzer_results=to_redact,
        operators={"DEFAULT": OperatorConfig("replace",
                                             {"new_value": "[REDACTED]"})},
    )
    return scrubbed.text, withheld

Two things about this that matter more than the library choice. The allow-list match here is deliberately simple; in production it needs normalisation for formatting variants and fuzzy matching for name spellings, or you will leak the subject’s own data as “third party” and redact it. And the detector’s confidence score is carried into the log, because a low-confidence hit is exactly the sort of thing you want a human to look at rather than trust blindly.

The log is the deliverable

The redacted bundle is what the requester sees. The withholding log is what defends you. If a supervisory authority questions whether you over-redacted, or the requester complains that you have hidden their own data, the answer is a per-document record of every span removed, its entity type, the confidence of the detection and the legal basis for withholding it. That record should be immutable, timestamped and tied to the specific export version that shipped. Treat it the way you would treat any other governance artefact in a governance-by-design pipeline — generated automatically as the work happens, not reconstructed afterwards from memory when someone asks.

Automated detection also does not settle the hard cases, and you should not pretend it does. Where a third party’s data is inseparable from the requester’s — a grievance one employee raised about another, a complaint that names the person complained about — redaction is a judgement about competing rights, not a pattern match. Those documents route to a human queue with the balancing question stated explicitly. The pipeline’s job is to make that queue small and to make everything in it a real decision, the same discipline that separates a lawful health-data release from a breach in EHDS secondary use.

Build the export as a filter with a memory, not a photocopier. The requester is entitled to their data; everyone else in those emails is entitled to be left out of it, and the log is how you prove you knew the difference.

Free interactive tool

Website compliance checklist

What your site has to do, based on what it actually does

Answer as much or as little as you like — the list builds as you go. Nothing is stored against your name and no email is required.

Free interactive tool

Interactive deadline calculator

Check which regulations apply to you and when

Regulation across the EU, UK, US and Asia-Pacific has moved considerably in the past eighteen months, and several headline dates have shifted more than once. Twelve questions, about three minutes.

Results are shown on screen — no email required. A dated summary is available to download, and can be sent on if that's more useful. What we do with your answers.

Most technology problems are not technology problems. They are control problems.

The systems exist. The investment has been made. The question is whether leadership can understand, direct, evidence, and sustain what those systems produce. Find out where control exists — and where it only appears to.

Full Governance by Sixteen Pillars

Govern your business. Prove your compliance.

A board assurance cockpit for EU-regulated financial firms — tamper-evident, hash-chained proof of governance across DORA, GDPR, NIS2, ISO 27001, the EU AI Act and MiCA. In development.

See what's coming