Skip to content

Choosing a technique

ShadowData offers four ways to handle a sensitive value. They differ in two things: whether the original can be recovered, and how much of it stays readable.

Technique Reversible? Output Use when
Anonymization No Redacted, not recognizable The value must be gone for good — logs, exports, test fixtures
Masking No Recognizable, mostly hidden A human needs to confirm a value — receipts, support screens
Pseudonymization Yes, with the key Opaque token You need the value back later, or need to join on it
Encryption Yes, with the key Ciphertext You need the underlying primitive directly

Anonymization vs. masking

Both are one-way, and the difference is intent.

Anonymization aims for unrecognizable: EmailAnonymization.anonymize_email hides the whole user part, so user@example.com becomes ****@****ple.com. Nobody reading the output should be able to tell whose address it was.

Masking aims for confirmable: partial_email leaves the first character, so user@example.com becomes u***@e******.com. A support agent can check that it matches the address the customer just read out, without the full value appearing on screen.

Masking necessarily leaks more. Use it only where a human genuinely needs the hint.

Pseudonymization: which of the two tokens?

Pseudonymizer offers two operations with very different properties.

pseudonymize produces a different token every time, even for the same input. Tokens cannot be correlated with each other, which is the safer default.

deterministic_pseudonym produces the same token for the same input, which is what lets you join records across datasets — and which also means the tokens leak equality.

Deterministic tokens are linkable by design

Repeated values stay visible as repeated tokens, and anyone holding the key can confirm a guessed value by recomputing its token. For low-entropy inputs such as email addresses or national identifiers, that is a realistic attack. Reach for deterministic_pseudonym only when you actually need the join.

Pseudonymization vs. encryption

Pseudonymizer is built on Symmetric, the Fernet wrapper. Use Pseudonymizer when you are replacing values in a dataset — it returns strings, handles key derivation for the deterministic mode, and raises a domain-specific error for bad tokens. Use Symmetric directly when you just need to encrypt a blob of text.

What none of this does

These helpers operate on values you have already identified. Finding the sensitive values in unstructured text is a separate problem — see PII detection — and one that no model solves perfectly. Treat detection as a first pass to be reviewed, not as a guarantee.