# How we answer GDPR data-subject requests before the deadline

Our Machine agent checks each GDPR access or deletion request, finds the person's data across our product database, builds the report well within the SLA and hands it to legal before anything is sent.

Canonical page: https://themachine.myapps.ai/use-cases/gdpr-dsar

When someone files a GDPR data subject access request, a timer starts. Once we
have confirmed they are who they say they are, we get one calendar month to
either show them everything we keep about them or erase it. That information is
scattered: a users table here, orders there, support history, an events table,
and a tangle of joins that someone has to know by heart. Run out of time, or
forget a table, and it is not only the requester who has a complaint. It is the
regulator.

Now an agent on Machine does the legwork. It picks each request out of our legal
inbox, confirms the sender's identity, tracks down their records in the product
database, and writes up an access or deletion report as a Google Doc. It runs
daily and finishes comfortably before the SLA. It does not delete data and it
does not write back to the person. The agent gathers and raises a flag; legal
makes the decision and sends the reply.

- **Team:** Machine
- **Runs on:** A daily schedule
- **Connected systems:** Gmail · Postgres · Google Docs
- **Mode:** Gathers and flags only · nothing goes out until legal approves

## The problem

The request shows up as a plain email. The data it covers sits in a schema that
was designed to run the product, not to satisfy privacy law. "Send me all my
data" turns into rows in users, orders and invoices, plus support tickets, login
history, marketing consent and anything else hanging off a customer ID. Those
tables were never meant to be read side by side, and the person doing it has a
month and no room for mistakes, every single time.

Repeat it often enough and the usual methods crack. A shared sheet that maps
where personal data lives is out of date the first time the schema moves. Handing
it to whoever has a spare afternoon means the identity check gets hurried or
dropped, and that check is what stops a stranger from fishing for someone else's
records. A script that searches and deletes in one go has no moment where it
pauses for a lawyer.

## What we built

Once a day a schedule starts an agent on Machine. It opens a fresh session that
looks in our Gmail legal inbox for new requests and checks each sender against the
identity details we already have. Then it runs read-only queries in Postgres over
every table tied to that person: their account, orders, support history and
consent records. The results go into a Google Doc laid out as an access report,
or as a deletion inventory when erasure is what they asked for. Legal receives
the doc with a suggested next step. Running a delete and emailing the requester
are both outside what the agent does.

## How it works

### Start once a day on a schedule

A **cron trigger** kicks the agent off daily. Each run gets a brand new
**session**, a fresh cloud computer (sandbox) used for that run alone. So every
request is handled from a clean look at the inbox and the database. Nothing from
yesterday sticks around, and an old identity check can never be recycled.

### Confirm identity first, search second

The rules for checking identity travel with the agent as a **skill**. They spell
out what proves the requester is really the data subject (the email matching the
account we hold, or the identity details they sent), what to do if the check
fails or is unclear, and how the GDPR clock really works: one month from a
verified request, with a single extension allowed for complex cases. No search
begins until a request clears this step.

### Give it access to the right tools

The agent reaches each system through scoped **connectors**, connections that
Machine brokers on the server so the model never handles a raw token. With them
it:

- **Pulls the request from Gmail**: the incoming email and any identity
documents attached, and it labels the thread once it has dealt with it.
- **Reads Postgres without changing it**: each table linked to the person,
including account, orders, invoices, support tickets, consent and login
history, so the picture of what we hold is complete.
- **Writes the report in Google Docs**: an orderly access report or deletion
inventory, one doc per request, that a lawyer can read top to bottom.

### Fence off what it can change

The agent writes exactly two things: the Google Doc it builds and the label on
the Gmail thread. Its Postgres access is read-only, so no delete is within reach,
even when the request plainly asks for erasure. It never sends the requester an
email. Credentials are stored encrypted in the **Secrets Manager** and only handed
to the agents you grant them to.

### Pass it to legal for review

Once the report is ready, the agent drops it into legal's review channel with a
suggested action, either fulfil the access request or go ahead with deletion,
plus the SLA date it is racing. Legal reads it, makes the call, and is the one
who writes to the requester or signs off on any deletion. The agent stops at the
flag.

> **The pattern**
> Every day a **cron** opens a fresh session. The agent confirms identity, reads
> the request in Gmail, searches Postgres read-only to find the person's data
> wherever it sits, and builds a report in Google Docs. It gathers and flags;
> legal decides, deletes and replies.

## Guardrails

These requests touch the most sensitive data we have, so the agent's access is
tight and its authority ends well before the decisions that count:

- **Isolation.** Each run lives in its own sandbox. The session can reach Gmail,
  Postgres and Google Docs and nothing else, and the only things it sends out
  are the finished report and the flag in legal's channel.
- **Read-only on the data itself.** Postgres is read-only for this agent. It can
  find a person's records in any table, but it cannot delete a row, change a
  record or run anything other than a `SELECT`.
- **Never replies to the subject.** The one message it sends goes to legal. It
  neither drafts nor sends a word to the person behind the request; that answer
  belongs to legal.
- **Deletion always waits for approval.** If a request asks outright for
  erasure, the agent only suggests it in the flagged report. Nothing is erased
  until a lawyer says yes and a different person carries it out.
- **Everything is code.** The identity rules, the map of tables and each
  system's permissions are files in the repo. They are versioned and only change
  through a reviewed **change request**, not a switch in a dashboard.

## The outcome

- **Every day:** Request inbox reviewed, with new requests handled the day they land
- **0 deletions:** Each erasure waits for a lawyer to approve it and someone to run it
- **1 flag:** A single finished report and suggestion per request, waiting for legal

These requests used to mean someone hand-joining tables against the clock. Now
legal gets a finished report with the data already found and a next step
suggested, long before the SLA runs out. The agent checks and gathers; people
decide, delete and reply.
