How Masking Works
Masking writes a copy of the input to the output with the sensitive values replaced. The tables, rows and relationships stay the same, so applications and tests work with the result. The input database is only read.
What MASKING mode does
In a table in MASKING mode, every column gets a transformer:
-
the one you set for that column in the configuration, if any;
-
otherwise, one chosen by the engine’s default rules from the column’s type and role;
-
otherwise, the safety mode decides. With
STRICT, the default, the run stops with an error rather than copy the column unmasked.
The output has the same rows as the input, unless you also subset the table.
How keys stay valid
By default, numeric and date keys are hashed: primary and foreign keys get unique_hashing if they’re numeric, and date_time_unique_hashing if they’re dates. A hashing transformer gives the same output for the same input, and different outputs for different inputs. For keys of other types, check which transformer the engine chooses, in the workflow’s Database view, or with dry-run in the CLI. So a customer’s ID gets a new value, every foreign key that refers to that customer gets the same new value, and joins still work.
In this example, the keys use the default, and the name and email columns use a person_generator:
| Column | Input | Output (illustrative) |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
To keep the original key values instead, set passthrough on the key and on the foreign keys that refer to it.
Choosing transformers
The default rules mask every column, but the values they produce may not look realistic or pass your application’s checks. For those columns, choose a transformer. The most common choices:
| You want | Transformer |
|---|---|
Realistic names, emails, usernames and phone numbers, consistent with each other |
|
Realistic addresses |
|
Card numbers, IBAN and BIC codes, and other financial values |
|
The same format with different characters, for IDs and codes |
|
Part of a value hidden, such as all but the last digits of a card |
|
Numbers close to the real ones |
|
Values that follow a pattern |
|
A field inside JSON or XML |
|
Your own logic |
|
The original value |
|
See Masking Transformers for the full list. The sensitive data scan finds the columns that hold personal data and suggests a transformer for each.
Consistent values
-
Hashing transformers are consistent by design: the same input always gives the same output.
-
Generators such as
person_generatorproduce a new value for each row. Setconsistent_with_columnto tie them to another column: withconsistent_with_column: "customer_id", all rows with the samecustomer_idget the same name. The valueselfties the output to the input value, so the same real name always becomes the same fake name. -
Across columns, one
person_generatoron several columns keeps them consistent with each other: the generated email matches the generated name. -
Across runs, hashing transformers keep giving the same output for the same input. For generators, see Repeatable runs.
KEEP and MASKING
Both copy rows from the input. KEEP passes every column through unchanged unless you set a transformer; MASKING masks every column unless you set otherwise. A common pattern is MASKING by default, with reference tables such as countries or currencies in KEEP:
default_config:
mode: MASKING
tables:
- table_name_with_schema: "public.country"
mode: KEEP
- table_name_with_schema: "public.language"
mode: KEEP
What masking doesn’t do
-
It doesn’t change the input database, unless you set the workflow to write into the same database.
-
It doesn’t mask a column that has
passthrough, or thatsafety_mode: RELAXEDpasses through. -
It doesn’t search free text for personal data. Transformers work on column values, or on the JSON or XML fields you select. For documents and other files, see Unstructured Data.
Will masking break my application?
The output keeps the schema, data types, constraints and keys. What can break is a value your application checks: a check digit, a format, a length or a business rule. For those columns, choose a transformer that produces valid values, such as finance_generator for card numbers and IBAN codes, or write the rule with the scripting_transformer, then test your application with the output.
Related pages
-
Masking Data: step-by-step guides.