Personal data in a prompt is a property of each request rather than of the code. A prompt is assembled from a conversation, a record lookup, a tool result, and what the user sent. Once a rule matches, the choice is which operator rewrites the span, and that choice is a trade between what the model can still work with and what a tool can still work with.
Six operators are available. The first four break a tool call loudly. Hand a tool an empty field, asterisks, a hash, or a placeholder and the tool fails. Something in the trace says it failed. The last two, pseudonym and format-preserving encryption, read as ordinary data to a tool, so they fail quietly. That is the trade.
What the four operators leave
Redact removes the span entirely. The model sees the sentence with a hole in it. The tool sees an empty argument, or no argument if the span was the only value in the field. A lookup fails.
Mask replaces the span with asterisks. The model sees a run of asterisks where a value was. The tool sees asterisks in place of the value it needs. A lookup fails.
Hash replaces the span with 64 hex characters. The model sees a hash it cannot use. The tool sees a hash. A lookup fails.
Placeholder replaces the span with a synthetic value like <PERSON_1>. The model sees a symbol standing for a value it is not told. The tool sees a symbol it does not recognise. A lookup fails.
All four fail the same way: the tool errors, the trace says so, and someone notices.
Pseudonym and format-preserving encryption
The point of pseudonym and fpe is realism. A pseudonym is a stand-in name, one that remains the same for the same input. FPE encrypts a card number into another card number that still passes the Luhn checksum. Both of these read as ordinary values to downstream code.
Hand a tool Grace Hughes, a name a real customer might have. The model sees a name and handles it as a name. The tool receives a name and calls lookup_customer(name="Grace Hughes"). It searches the customer table for Grace Hughes. It finds someone. It returns 200 OK. Nothing in the trace says it found the wrong customer.
Hand a tool 4532-7712-0483-1965, a card number that passes the Luhn checksum. The model sees a valid card number and reasons about it as one. The tool receives a card number and calls verify_payment(card="4532-7712-0483-1965"). The payment processor returns a response. The model continues. The request succeeds quietly with the wrong account.
That silence is the reason for the trade.
Why realism is the problem
Pseudonym and fpe exist because one-way redaction breaks the work. A support ticket that reads “the payment from card was declined twice”, with the number removed, gives the model less to reason about. A lookup against a placeholder finds nothing and something notices. The business switches off the guard because the tool cannot work.
The replacements that read as real serve the workflow and defeat the trace. The first four operators break loudly. Pseudonym and fpe break silently, and the first sign of the break might be a customer complaint about a wrong charge.
What to do about it
Where a tool consumes the value and cannot be told the real one, placeholder is the operator to reach for. It produces worse text for the model and a failure somebody notices, which on a path ending in a lookup is the better trade. The model learns that the tool cannot find a match and tries another approach or tells the user the lookup failed.
Refusing the call outright is the other answer. A rule’s when clause can read what server is being called and what tool is being used. A rule can deny the call on that server and that tool, and the model never makes it.
Choosing pseudonym or fpe is a decision the team that owns the tool has to be in on, because only they know whether their lookup can tell a real customer from a plausible stand-in.
Restore lists and reversals
A rewritten value can be turned back into the original before the tool sees it. An MCP server can declare a restore list that names the entity types it is allowed to receive in the clear. That declaration says the server is inside your boundary, a system of record that may see real values because a lookup against a stand-in finds the wrong one or none.
Restore only applies at a hop the gateway itself dials, because that is the only place anyone can promise anything about where the value will go. A server without a restore list receives the stand-in by design.
Names are the exception. A pseudonym is a many-to-one fold followed by a keyed pick from a word list. Neither half inverts. The forward map takes unbounded text to a short plausible name, so anything that inverts it has stored the original. A server that wants the real customer name and has no restore list keeps failing quietly, and stays that way.
The pattern
The pattern reaches past pseudonym and fpe. An operator that makes the rewritten value plausible buys the workflow at the cost of a quiet failure. An operator that makes it implausible buys a loud failure at the cost of the workflow. The choice is which failure is worse.
That choice is made per rule by the operator, because only the team behind the tool knows what it does with the value. A gateway that picks one answer for all tools and calls is picking wrong for most of them.
As of 4 September 2026
pistra ships six operators: redact, mask, hash, placeholder, pseudonym, and fpe. Pseudonym and fpe are the two operators whose output reads as real. The other four fail loudly. FPE uses FF1 from NIST SP 800-38G and is checked against NIST's own worked examples. A pseudonym never inverts. An MCP server's restore list applies only at a hop the gateway dials, and a server without one receives stand-ins. See Redact PII from model output and the personal data page.