Security & Hashing
Private mappings, placeholder disclosure, and the trust boundary between Detection and Generation.
The private mapping is the secret
The mapping from placeholder to original user content is the only thing that can restore protected content. Keep it in memory. Do not log it, send it to analytics or crash reporters, or persist it outside a platform keystore. Keep original content out of telemetry that runs before Detection.
What a Generation provider sees
| Strategy | Value | Equality | Type |
|---|---|---|---|
sequential() | not exposed | within a privacy session | yes ([EMAIL_1]) |
hashed({ secret }) | not exposed | stable with the key | yes |
token() | not exposed | within a privacy session | not exposed |
token({ secret }) | not exposed | stable with the key | not exposed |
Equality can be useful for stable references, but it is metadata. Equal
canonical values reuse one token() during a privacy session; a new session
breaks that link. token() is still the safer default for type obscurity and
machine-parsed output.
Why unkeyed hashing is forbidden
A plain hash of an email or phone is guessable: a provider holding the hash can
recompute candidates offline. hashed and token({ secret }) use the key you
supply, so generate and store a strong random key; the strategies do not check
its entropy. Expo apps that install expo-crypto and expo-secure-store can
use getOrCreateDeviceSecret() from local-pii/expo. Without the key, a
correct guess cannot be verified.
Tool arguments are a disclosure boundary. Rehydrating an argument gives your tool the original value; if that tool forwards it elsewhere, that is a new disclosure that your application owns. See Tool Calls.