Privacy and data retention
Every field you send to a model becomes data you must protect, retain and delete. Minimise it, schedule it, and make deletion reach every copy.
Data minimisation is a design decision
Every field you send to a model is a field you now have to protect, retain and delete. The cheapest data to govern is the data you never collected, so start by asking which fields the prompt actually needs. A support assistant that answers billing questions rarely needs a date of birth, and a summary rarely needs an account number.
Minimisation is not the same as redaction. Redaction removes a value after it has entered the system; minimisation keeps it out of the request, the log and the trace in the first place. The second is stronger because there is nothing to leak, nothing to expire and nothing to explain during an audit.
Purpose limitation follows from the same question. Data collected to answer a ticket should not quietly become training data, evaluation data or a dashboard dimension. Each new use is a new decision with its own lawful basis, and the design document should name the uses rather than assume them.
Retention is a schedule, not a setting
A retention policy is a table: data class, purpose, store, retention period, deletion mechanism and owner. Prompts might live seven days, traces thirty, aggregates two years, and a fine-tuned adapter as long as the base model it corrects. Without the table, every store invents its own answer.
Pick the period from the purpose, not from the storage bill. A trace kept for debugging has no reason to outlive the debugging window, and an evaluation set kept for regression has a reason to live as long as the suite. The period is a statement about why the data exists at all.
Write the schedule where the code can read it. A retention table in a wiki drifts from the job that deletes rows, and the drift is invisible until an audit finds records older than the policy allows. A job that reads the same table the policy names cannot disagree with it, and the owner in that row is the person who answers when it does.
Crypto-shredding with a per-subject key
from cryptography.fernet import Fernet
key = Fernet.generate_key()
cipher = Fernet(key)
token = cipher.encrypt(b"card 4111 1111 1111 1111")
# Deleting the key makes every record encrypted under it unreadable.
# The row can stay; the subject's data cannot be recovered.
print(token[:16])A retention clock per data class
Run the schedule and see which records have expired. Then add a cache store to the prompt record and confirm the deletion fan-out picks it up.
Deletion has to reach every copy
A delete request is a fan-out, not a row update. The primary database, the cache, the search index, the vector store, the trace store, the evaluation set and the analytics warehouse may each hold a copy. The job is finished when every store reports back, and that report is the evidence.
Derived data is the part teams forget. An embedding is a representation of the text, a summary is a rewrite of it, and a fine-tuned adapter may have memorised it. Deleting the source row while the vector index still returns the chunk is a deletion that exists only in the ticket.
Keep a tombstone with the subject id, the stores that acknowledged and the timestamp. The tombstone contains no personal data, so it can outlive the records it describes, and it is what lets a later audit answer whether the deletion completed.
A backup is a copy with its own clock. Either the backup expires within the promised window, or the restore procedure has to replay deletions before the data is served again. A fine-tune is the same problem with no expiry date.
Requests, and the record of them
A subject access request asks what you hold, and a deletion request asks you to stop holding it. Both need an index from a person to their records, and most systems do not have one. An email address is a start, but it appears in free text, in a hash and inside a prompt.
Pseudonymisation helps the join without keeping the identifier in every store. Store a keyed hash of the subject id beside the record, keep the key in a separate system, and the trace can be linked to a request without carrying the email. Deleting the key is then a second, cheaper deletion path.
Answer within the legal window, and answer in the same units the request used. A response that lists six rows when the user asked about their account is a response that will be disputed. The record of the request, the search performed and the stores covered belongs in the audit log, not in the response.
Erase one subject from every store
Run the fan-out and confirm every store reports. Then add an eval store that holds a rewritten case for the same subject and make the deletion cover it too.
Check what you learned
One question at a time. A wrong answer explains itself — take another go.
Part 1 of 5
Why is minimisation stronger than redaction?
