What changes for your application: nothing, by default.Your own API keys receive real values, so the text you read back is identical to what you read before you protected anything. Aliases are what sits on our side. You only see one if you deliberately choose a setting that keeps the value from your app too, or issue a key that is restricted on purpose.
What an alias is
An alias is a stable placeholder that stands in for one sensitive value. It looks like this:PERSON_AADHAAR knows whose Aadhaar number is missing without looking anything up, which is the point of putting the readable part first.
The twelve characters leave out the ones people confuse when reading a string aloud or copying it from a screenshot, so there is no 0 or O, no 1 or l or I.
The leading word groups the alias by what it is about: PERSON, PAYMENT, HEALTH, PLACE, DEVICE, SECRET, or CUSTOM for a field type you defined yourself.
When a memory carries an alias, the sentence around it still reads:
The same value always gets the same alias
This is the property everything else depends on. Two documents mentioning the same phone number produce the same alias, so anything that compares memories still works: deduplication still merges duplicates, a correction still supersedes the thing it corrects, and the entity graph still sees one identity rather than two. Before matching, Synap puts the value into a canonical form, so different spellings of the same thing collapse to one alias:
An alias is shared at customer level, within one instance. Two users of the same customer who give the same phone number get the same alias, so a question that spans both their memories can still be answered. The same number under a different customer, or a different instance, gets a different alias, so nothing about one tenant’s data can be inferred from another’s.
Why search still works
This is the part that would break silently if it were not handled, so it is worth understanding. Your memory store holds[[PERSON_PHONE_h2n7v5cx8m0d]], not 9876543210. Someone searches for 9876543210. Every layer of retrieval is now looking for characters that are not there, and finds nothing. The product looks like it forgot, and the reason has nothing to do with memory quality.
So your query goes through the same detection step your content did. Anything in it that your policy stores as an alias is swapped for that same alias before retrieval runs, and the search then looks for exactly what was written down. This is a hard requirement in the design, not an optimisation.
Three rules keep that safe:
- A query never creates an alias. It only looks one up. Searching for a value Synap has never seen leaves the query alone, which is the right answer: no memory holds that value either.
- A query is rewritten only for field types you actually store as aliases. If your policy keeps real values for a field type, the store holds the real value and rewriting would break the search it is meant to fix.
- A failed lookup never blocks a search. The query goes through untouched, which is the same answer as “we have never seen this value”.
What your application receives
On the way out, Synap puts real values back for exactly the field types the caller is entitled to, and leaves everything else as an alias. Entitlement is decided by two things, in this order:- Your policy sets the ceiling. It is the “Your app gets” column of the settings table. Choose Protect at rest and your app gets real values. Choose Protect from everyone and it gets aliases.
- The grant on the API key that made the call can narrow that, and can never widen it. A key marked
maskedreceives placeholders even for field types your policy would hand over.
Restricted keys and caching
If you use two keys with different grants against the same instance, the entitlement is part of what identifies a cached read, so a privileged fetch can never answer a restricted key’s request. Values are put back after the cache is read, never before, so nothing cached holds a real value.Aliases and “do not store it”
A field type set to Do not store it still gets an alias, so the same value can be recognised when it appears again and occurrences can be counted. What it does not get is anything the value can be recovered from. A reveal on it returns nothing, for anyone, and the memory keeps a short description of what was taken instead of the value. Field types on the floor go further and get no alias at all, so there is nothing associated with them anywhere.What this costs you
Reads pick up a small amount of extra work to look up and put values back, against a fetch that already takes far longer than that step. Ingestion picks up the detection pass, and ingestion is asynchronous, so you do not feel it in your request path. Every change to this feature is gated on the same benchmark suite Synap runs for retrieval quality, with a hard limit on how far any benchmark may move.Next steps
Sensitive Data Protection
The categories, the six settings, and the floor.
Configure it
Set a policy, and test it before approving.
Erasing a person
What deleting someone makes unreadable, and what survives.
Sensitive data FAQ
Will this break my app, and what happens to memories I already have.