How OpenDot keeps your email address away from the cloud model
OpenDot swaps personal details for tokens right before a request leaves your computer, and swaps them back when the answer comes home. Here is how the boundary works, and where it stops.
OpenDot runs a team of AI agents, called Dots, on your own computer. Some of them read your inbox, your calendar and your files. Most people still want to use a strong cloud model for the thinking. That leaves an awkward question: how do you let a cloud model help with your email without handing it every address, phone number and card number in there?
Our answer is a boundary. The transcript on your disk keeps the real values. Only the request that goes to the model provider carries stand-ins.
Tokens instead of values
Right before each call to the model, OpenDot scans every text part of every message: what you wrote, what the Dot wrote back, tool results, background events. Anything it recognises as personal is replaced with a token like ⟦EMAIL_1⟧ or ⟦PHONE_2⟧.
The same value always gets the same token inside a Dot, so the model can still reason about it. “Reply to ⟦EMAIL_1⟧ and copy ⟦EMAIL_2⟧” is a perfectly good instruction. It just doesn’t know who those people are.
We picked the ⟦ ⟧ brackets on purpose. They almost never appear in normal text, and models copy them back faithfully.
What it looks for
Detection is deliberately boring. Boring is testable.
- Email addresses, by pattern.
- Phone numbers, parsed with libphonenumber and kept only if they are valid for a real numbering plan.
- Card numbers that pass the Luhn check, and IBANs that pass the mod-97 check, so a random long number isn’t flagged.
- US social security numbers, IP addresses, and passwords embedded in URLs.
- Secrets: API keys in the common formats, JSON web tokens and private keys.
- Names, addresses and any custom terms you add yourself.
Name detection is off by default, because guessing names in free text gets things wrong both ways. You can switch it on, or list the names that matter to you.
Getting the real values back
Tokens would be useless if they leaked into your actual email. So the boundary works in both directions:
- When the model asks to call a tool, say “send a draft to ⟦EMAIL_1⟧”, OpenDot restores the real address before the permission check and before the tool runs. The approval you see shows the real recipient.
- When the model answers, the tokens in its reply are restored before the message is saved. What you read, and what sits on disk, is the real text.
The mapping between tokens and values lives in a small vault per Dot, encrypted with AES-256-GCM. Its key sits in your operating system’s keychain, and it is deleted with the Dot.
When it runs
By default, masking switches on when a Dot uses a cloud model and off when it uses a model running on your own machine, where there is nobody to hide from. You can force it either way per Dot.
Where it stops
Some limits are worth stating plainly:
- Images are not scanned. A screenshot of an email goes through as it is.
- Detection is pattern-based. It catches well-formed emails, numbers and keys. It will not catch “my sister’s new flat near the station”.
- It protects you from the model provider, not from yourself. If you approve a Dot sending something, it gets sent.
None of this replaces choosing a provider you trust. It makes that choice matter less for the details that matter most.
The code is open source, so you don’t have to take our word for any of this. The boundary lives in desktop/src/main/runtime/extensions/pii.ts, and the full design is in the security spec.