Skip to content

Share a result without the PII?

Rewrite the columns, send the link.

Someone from another team asked for the numbers in a file. The file also had names and email addresses in it. I deleted those columns by hand, sent the rest as an attachment, and hoped I had found them all. That week an agent on my machine asked to read the same file, and I had no answer ready for it either.

Today ​

Sharing the object from the console would have handed over everything. I downloaded the file, opened it in a spreadsheet, and scrolled across looking for anything personal. I deleted the name column and the email column. I deleted a column of codes too, because I wasn't sure about it. I saved a copy under a new name and attached it to an email.

Now it lives in my sent folder and in their inbox, and there is no way to take it back.

  1. Cloud consoledownload the file
  2. Spreadsheet appdelete columns by hand
  3. Spreadsheet appsave a copy
  4. Emailattach and send
one hand edit, two inboxes, no expiry

I don't think I did anything wrong, and neither did the spreadsheet or the email. The shared assumption was that sharing a result means sending a file: a whole copy, edited by hand, with no rules attached to it once it leaves. And what I decided about the email column lived in one spreadsheet, where the agent would never see it.

Ideal ​

So I tried to start from what I was really doing. I wasn't sending a file. I was answering a question, and the answer needed some columns and not others.

The columns that must not leave have names. I could have listed them before I opened the file. So the rule belongs at the door, stated once per column: this one goes as it is, this one is hidden, this one is replaced. And it is the same door whoever stands outside it. A colleague opening a link and an agent calling over MCP are both data leaving my machine, so I think the rules should be written once and hold for both.

Hidden doesn't have to mean deleted. A keyed hash keeps equal values equal and nothing else. A mask stars out part of a value. Format-preserving encryption swaps a value for another of the same shape, so a phone number still looks like one. And an email address inside a note has no column to be named by, so a second list matches what a value says and replaces only that.

The last part is the envelope. An attachment can't expire. A link can, if whatever serves it checks the date.

The share dialog for nl_train_stations.parquet: each column set to None, Mask, Hash or FPE (uic is FPE, name_long masked for characters 0 to 4, slug hashed to 16 hex characters), three sample rows shown before and after, an expiry of one week picked, and Copy URL, Email and Copy key.
The share dialog for nl_train_stations.parquet: each column set to None, Mask, Hash or FPE (uic is FPE, name_long masked for characters 0 to 4, slug hashed to 16 hex characters), three sample rows shown before and after, an expiry of one week picked, and Copy URL, Email and Copy key.

That is the dialog for the train stations file. Each column opens on what my rules already say, and I can change one for this share alone. The rows at the bottom show each value as it is and as it will go.

In the code both readers go through one implementation on my own machine. Every call an agent makes asks for both lists and has no way to ask for less, and every column it gets rewritten is marked as encrypted. A share asks for the same two lists, with the dialog's choices tried first, and the preview is that same answer.

What differs is the key. An agent's answers use one key per install, so a value stays the same across sessions. A share gets a key of its own, never put into the link, so two shares of one file don't line up with each other or with what an agent saw.

The link lives from one day to one year, one week by default.

Where it stops ​

A column can't be dropped from a share yet. A rule that says "drop" opens as a hash there, so the receiver sees the header over meaningless values, while an agent never sees the column at all. And a small share travels inside the link, carrying its expiry as a date the viewer checks. Anyone who keeps the link keeps the data. Only a stored share can truly stop answering.

A share is rows, not files, up to 5,000 of them. An agent can read more than rows, and a drawing or a window of raw bytes has nothing for either list to catch, which is why an agent starts without the tool that reads them.

Rewrite the columns, send the link.