Skip to main content
Rows an agent reads become text in a model’s context. Masking decides which values it may see.
Tokenization is the one that keeps agents useful: alice@example.com always becomes the same tok_…, so the agent can group, join, and refer to it — and can hand the token back to Warden in a later operation — without the address ever entering its context.

Masked inside the statement

Masking applied to result rows is defeated by one expression:
So where the engine allows it, masking happens inside the statement. Each governed table is replaced by a subquery in which the column is already masked, and the agent’s own SQL can only reach the masked value — through an alias, a function, a join, or anything else it writes. The certification suite attacks exactly these paths. Masking keys come from masking_salt, so tokens are stable across restarts and consistent everywhere the same value appears. Treat the salt as a secret: it is what stops a token being reversed by someone who can guess likely inputs.

Failure discards the result

If a masking rule cannot be applied, the entire result set is discarded and the operation returns masking_failed. Returning partially masked rows would leak precisely the values the rule exists to protect.

Column restriction is separate

Masking transforms a value the agent may see. Column restriction means the column is not in the projection at all — SELECT * returns the permitted columns, and naming an unpermitted one is refused. Use restriction for columns the agent has no business reading, and masking for ones it needs to work with but must not read.

What masking is not

It is not encryption, and it is not a substitute for not storing the data. A determined agent that can read enough masked values and correlate them with data it already has can sometimes infer the original. Masking raises the cost and removes the accident — an agent pasting a customer list into a prompt — which is the realistic threat.