Governance in practice · 1

Personal data in a prompt

Asked what personal data leaves the company, a code review cannot answer, because a prompt is assembled at runtime out of a conversation, a record lookup and a tool result. The request itself is where the question has an answer.

governance platformoff the path: before the call and after it
response cachea hit never reaches the provider
clientkey · model · body · tool call
the last place the data is still yoursbefore the request leavesdecideredactmeterrecord
processora model, usually in another country
recordthe decision, signed; never the prompt
detectorcalled out to with a string
A prompt sent to a hosted model is a disclosure to a processor. The hop is where that can still be changed.

The assistant goes live next month, and legal wants the list of personal data that leaves the company and where it goes. The list does not exist, and the reason is not carelessness.

Where the data actually is

An engineer can show legal the code. The code contains a template, a system prompt, and a call. It does not contain the data, because a prompt is assembled at the moment of the request out of whatever the conversation has accumulated, whatever a record lookup returned, whatever a tool answered with, and whatever the user pasted in.

So “what personal data leaves” is not a property of the application. It is a property of each request, and it differs in every one of them. A review can establish what the code intends to send. What was actually sent is visible only to something watching the traffic.

That is awkward for a programme built on documents, and it is the job the enforcement plane exists to do. Data protection law has never described an artifact you can inspect. It attaches to a disclosure at the moment the disclosure is made, and a prompt to a hosted model is a disclosure to a processor, usually across a border.

What the path can do

It can see the data, in the body as assembled, including inside the arguments of a tool call, which is where personal data most often travels without anybody meaning it to.

It can change the request before it leaves, which is the one intervention that changes what was transferred. A control that runs earlier constrains what the code was likely to send. A control that runs later describes what already went.

It can say what it did. The same pass that finds a span and replaces it writes down which rule fired, on which span, under which revision of the configuration. Evidence assembled by a different system afterwards is a claim about the enforcement. This is a record of it.

Redaction that survives contact with the business

PII controls get switched off after a month because one-way redaction breaks the work. A support ticket that reads “the payment from card [REDACTED] was declined twice” gives the model nothing to reason about, and a tool that looks the value up finds no customer.

So the replacement matters as much as the detection. A stand-in can be a placeholder, or a pseudonym that is stable for the same input, and both of those are one-way by design. It can also be format-preserving: a card number replaced by a different card number that still passes its checksum, so the model handles it as a card and a recognizer downstream still finds it. Those are different promises, so they are keyed separately. The pseudonym key can be rotated whenever you like, because nothing has to reverse it, and the format-preserving key is an AES key with the obligations that implies.

Then there is the way back. An MCP server can name the entity types whose format-preserved values are turned back into the originals in that server’s tool arguments, after the guardrails have run. The default is to restore nothing, which is the right answer for every server nobody has deliberately decided about. Naming a type there declares that this server is inside the boundary: a system of record that may see the real values and needs them, because a lookup against a stand-in finds the wrong customer or none.

That declaration is about the counterparty, not the rule, so it lives beside the server’s URL. And it applies only at a hop the gateway itself dials, since a promise about a destination holds only where you make the connection.

What pistra does not know

There is no PDPL mode and no GDPR mode. Neither word appears anywhere in the code, deliberately.

The gateway has entity types, rules that act on them, and controls identifiers on a rule that ride onto every record that rule decides. Your data protection officer decides which entity types count as personal data in your context, which rule discharges which control, and what the identifier is called. The gateway makes the rule happen at the moment of the call and signs what it did.

A compliance mode would be a vendor’s reading of a law, on a date, applied to your data. When the reading is wrong you inherit it without being told, and when the regulation moves you wait for a release. That is the argument post 5 made about unified APIs, in a different regime.

When you do not need this

If personal data lives in a database and your application never puts any of it in a prompt, an inspection hop buys you nothing. A code assistant on a repository with no customer data in it, a classifier over documents that were already yours, an internal search over an internal wiki: those are governed by who has an account, not by what is in the body.

And if what you want is the mapping, a pack that labels entity types against a named regime’s categories so you can hand it to an auditor, a detector vendor who sells that will get you there faster than we will. You will still need something holding the connection to act on the verdict. Buy the labelling from whoever labels for a living.

The dates

The AI Act’s obligations for high-risk systems arrive in December 2027. The transfer obligation arrived the first time one of your applications called a model, and in Saudi Arabia the transition period for the PDPL ended on 14 September 2024. One of those needs a plane that runs today.

Sources, as of 29 August 2026

Saudi Arabia's Personal Data Protection Law was issued by Royal Decree M/19 on 16 September 2021 and amended on 27 March 2023; the Implementing Regulations were issued in September 2023 and the transition period ended on 14 September 2024. The Regulation on Personal Data Transfer Outside the Kingdom sits alongside them, and SDAIA administers both (sdaia.gov.sa). Regulation (EU) 2026/1744 defers standalone high-risk obligations under the AI Act to 2 December 2027 (eur-lex.europa.eu).

pistra, per the docs of the same date: the anonymizer offers presidio-anonymizer's four operators plus placeholder, pseudonym and fpe; pseudonym_key is any-length hex and fpe_key is an AES key of 16, 24 or 32 bytes; an MCP server's restore list may only name types some detector emits and the fpe operator has an alphabet for, and it defaults to empty. Nothing in the codebase names a data protection regime.

All posts