Testland
Browse all skills & agents

data-masking-techniques-reference

Pure-reference catalog of data-masking techniques and de-identification privacy models. Enumerates the seven canonical masking operators (substitution, shuffling, number/date variance, encryption, hashing, nulling, masking-out / character-scrambling) plus tokenisation, redaction, format-preserving encryption, and Microsoft Presidio's six built-in operators. Distinguishes reversible techniques (pseudonymisation candidates per GDPR Art. 4(5)) from irreversible techniques (anonymisation candidates), and maps them to NIST SP 800-188 privacy models - k-anonymity, l-diversity, t-closeness, differential privacy (deep model definitions in references/). Cites ISO/IEC 20889:2018 for the standard taxonomy. Use to pick the right masking operator per field type and risk level.

Install with skills.sh (any agent)

npx skills add testland/qa --skill data-masking-techniques-reference
View source

data-masking-techniques-reference

Overview

Masking is the act of transforming a real value into a substitute that breaks the link to the original subject while preserving testable properties (format, distribution, referential integrity). Which technique is correct depends on three things: whether the result must be reversible, whether the field is referentially shared across tables, and what privacy model the dataset must satisfy.

This skill is the pure reference that the pipeline builder (pii-masking-pipeline-builder) and leak-detection audits draw from to choose operators per field.

When to use

  • Picking the right masking operator for a field (pii-categories-reference classified as PII).
  • Deciding whether output is pseudonymised (still in GDPR scope) or anonymised (out of GDPR scope).
  • Sizing a privacy model (k-anonymity / differential privacy) against utility loss.

How to use this reference

  1. Classify the field as direct identifier, quasi-identifier, or sensitive attribute (pii-categories-reference).
  2. Decide the reversibility need - must an authorised consumer recover the real value? If yes, pick a reversible operator (encryption, FPE, tokenisation, deterministic substitution); if no, pick an irreversible one from the seven-techniques catalog below.
  3. Preserve what the test needs - format, distribution, or referential integrity across tables narrows the operator (deterministic substitution / salted hashing keep joins; shuffling keeps a column's distribution).
  4. Confirm the scope outcome in the pseudonymisation-vs-anonymisation table - reversible output is still personal data under GDPR.
  5. Layer a dataset privacy model when quasi-identifiers survive per-field masking - k-anonymity through differential privacy, in references/privacy-models.md.
  6. Cross-check the anti-patterns before shipping the pipeline.

The seven canonical masking techniques

Drawing from the Wikipedia data-masking taxonomy (en.wikipedia.org/wiki/Data_masking (opens in new window)) and ISO/IEC 20889:2018 (cite by stable ID; standard text behind paywall):

1. Substitution

Replace the real value with an authentic-looking value from a lookup table - "John Smith" → "Maria Garcia."

  • Reversibility: Irreversible if the lookup is random per row. Reversible if the same input always maps to the same output (deterministic substitution); used as pseudonymisation.
  • Referential integrity: Preserved when deterministic (hash(real_id) → fake_id keeps joins intact across tables).
  • Use for: Names, addresses, employee IDs that must remain joinable across tables.
  • Tooling: Presidio replace operator (presidio.dataprivacystack.org/anonymizer (opens in new window)), Faker library generators (faker-synthetic-data).

2. Shuffling

Randomly rearrange values within a column - salaries column gets shuffled, each row keeps a real salary but no longer the right person's salary.

  • Reversibility: Irreversible.
  • Distribution: Preserved exactly (it's the same set of values, reordered).
  • Use for: Columns where the distribution matters for analytics but the per-row truth is sensitive (salary, performance score).
  • Risk: If rare values exist (1 person earns $5M), shuffling doesn't anonymise them - the value identifies its row position cluster.

3. Number / date variance

Apply a bounded random offset: salary ± 10 %, dates ± 120 days (Wikipedia data-masking page).

  • Reversibility: Irreversible without the per-row offset key.
  • Use for: Continuous numeric / temporal fields where approximate values are useful (analytics) but exact values are sensitive.
  • Risk: Bounded variance may leak the original value (date ± 120 days narrows to a year; salary ± 10 % narrows to a bracket).

4. Encryption

Apply a cryptographic algorithm with a key. Two sub-variants:

  • General encryption (AES-256-GCM, etc.) - output is opaque ciphertext; reversible only with the key. Use for fields that must round-trip back to plaintext for authorised consumers.

  • Format-preserving encryption (FPE) (FF1 / FF3 per NIST SP 800-38G) - output has the same format as input (16-digit card → 16-digit ciphertext). Use when legacy systems validate format.

  • Reversibility: Reversible (key required).

  • Use for: PII that must round-trip for authorised business logic; legacy-format requirements.

5. Hashing

Apply a one-way hash (SHA-256 / SHA-512) with optional salt.

  • Reversibility: Irreversible (assuming the salt + hash are cryptographically sound and the input space isn't enumerable).
  • Determinism: Same input → same hash. Used as a deterministic pseudonym preserving referential integrity.
  • Risk: Low-entropy fields (SSN with known format) are enumerable under unsalted hashing - attacker pre-computes all 1 billion possible SSNs. Always salt + per-tenant key.
  • Tooling: Presidio hash operator with hash_type = "sha256" or "sha512" and salt parameter.

6. Nulling out / deletion

Replace the value with NULL or remove the column entirely.

  • Reversibility: Irreversible.
  • Use for: Fields with no analytical value to non-prod consumers (auth tokens, security questions, plaintext passwords).
  • Risk: Schema constraints (NOT NULL) may block the operation; pipeline must coordinate with schema.

7. Masking-out / character scrambling

Show partial value - credit card "**** **** **** 1234," email "j***@example.com."

  • Reversibility: Irreversible (unmasked characters can leak some info - last-4 of card identifies brand + issuer family).
  • Use for: Customer-facing displays where the user must recognise their own value; analytics that need partial info.
  • Tooling: Presidio mask operator with chars_to_mask, masking_char, from_end parameters.

Additional techniques

Tokenisation

Replace the real value with a token (random opaque string) and store the real-value → token map in a separate, access-controlled vault.

  • Reversibility: Reversible via the vault (authorised lookup).
  • Use for: Payment processing (PCI-DSS-driven), any field where the token must round-trip for authorised consumers without exposing the value to the consuming system.

Redaction

Remove the value entirely (no placeholder, no length signal).

  • Reversibility: Irreversible.
  • Use for: Free-text logs, screenshots, document exports where even the presence of a field is sensitive.
  • Tooling: Presidio redact operator (no parameters).

Synthetic substitution

Replace with a synthetically generated value preserving distribution / format (faker-synthetic-data; synthea-healthcare-data for health records).

  • Reversibility: Irreversible.
  • Use for: Demo / training environments where realistic-looking but never-real data is required.

Microsoft Presidio anonymizer operators

Per presidio.dataprivacystack.org/anonymizer (opens in new window), the Presidio Anonymizer engine supports six built-in operators:

OperatorParametersReversibleMaps to canonical technique
replacenew_value (defaults to <entity_type>)No (random) / Yes (deterministic substitution)#1 Substitution
redact-NoRedaction
maskchars_to_mask, masking_char, from_endNo#7 Masking-out
hashhash_type (sha256 / sha512), saltNo (one-way)#5 Hashing
encryptkeyYes (with key)#4 Encryption
customlambdaDepends on lambda(caller-defined)

Invocation: engine.anonymize(text=, analyzer_results=, operators={"PERSON": OperatorConfig("replace", {"new_value": "BIP"})}).

OperatorConfig constructor signature: OperatorConfig(operator_name, params={}) (Presidio docs).

Reversible vs irreversible - pseudonymisation vs anonymisation

GDPR Art. 4(5) defines pseudonymisation as "processing of personal data in such a manner that the personal data can no longer be attributed to a specific data subject without the use of additional information, provided that such additional information is kept separately" (gdpr-info.eu/art-4-gdpr/ (opens in new window)).

TechniquePseudonymisation?Anonymisation?
Deterministic substitution (same input → same output)-
Random substitution-
Shuffling-✓ (when distribution-only)
Number / date variance-✓ if variance ≥ identifying granularity
General encryption (key kept)-
FPE (key kept)-
Salted hashing (salt kept separately)-
Unsalted hashing of low-entropy field✗ (re-identifiable by enumeration)
Nulling-
Masking-out (partial)depends on revealed charsdepends
Tokenisation (vault kept)-
Tokenisation + vault destroyed-
Redaction-
Synthetic substitution-

Implication: A "masking pipeline" output that uses reversible techniques is still personal data under GDPR - it remains in scope. Only fully irreversible output is out of GDPR scope per Recital 26.

Privacy models - NIST SP 800-188

NIST SP 800-188:2023 formalises statistical privacy models that sit above the per-field operators - pick one for the whole dataset's disclosure risk once quasi-identifiers remain after masking:

  • k-anonymity - every record indistinguishable from k-1 others on the quasi-identifiers (generalise / suppress / aggregate).
  • l-diversity - k-anonymity plus l well-represented sensitive values per equivalence class.
  • t-closeness - l-diversity plus a sensitive-attribute distribution within t of the overall distribution.
  • Differential privacy - a formal guarantee bounded by the privacy budget ε, achieved by noise injection on query outputs.

Full definitions, achievement methods, weaknesses, and ε / k guidance (with NIST + primary-source citations): references/privacy-models.md.

Picking a technique per field

Field characteristicRecommended techniquePrivacy model layer
Must round-trip for authorised consumer (payment processing)Tokenisation (vault) or FPEnone (reversible)
Must join across tables, opaque value OKDeterministic substitution / salted hashingk-anonymity on quasi-identifiers
Free-text PII inside a log lineRedaction or replace-with-<TYPE> (Presidio analyzer + anonymizer)-
Continuous numeric for analyticsNumber variancet-closeness if sensitive attribute
Categorical demographic (race, etc.) for analyticsGeneralisation + l-diversityl-diversity
Statistical query releaseDifferential privacy mechanismDP
Demo / training, no analytics utility neededSynthetic substitution (Faker / Synthea)n/a (no real data)

Worked example - masking a non-prod customers table

An analytics team needs a non-prod copy of a customers table. Walk each field through the steps in "How to use this reference":

FieldNeedOperatorScope outcome
customer_id (FK, joined across tables)Opaque but joinableDeterministic substitution / salted hashing (#1 / #5)Pseudonymised - reversible via key
full_nameNo analytics valueRandom substitution (Faker)Anonymised
emailSupport must recognise own valueMasking-out j***@example.com (#7)Partial - depends on revealed chars
national_id (SSN)No analytics value; enumerable formatNulling out (#6) - never unsalted hashingAnonymised
date_of_birthAge band usefulGeneralise to a band (age 47 → "40 - 50")Anonymised (k-anonymity input)
salaryDistribution usefulNumber variance ± 10 % (#3)Anonymised - t-closeness if sensitive
auth_tokenNo analytics valueNulling out / deletion (#6)Anonymised

Resulting scope: because customer_id uses a reversible deterministic map, the output is pseudonymised - still personal data under GDPR Recital 26. To move the dataset out of scope, destroy the substitution key so customer_id can no longer be re-linked. The remaining quasi-identifiers (date_of_birth band, salary bracket) then need a dataset privacy model - see references/privacy-models.md.

Anti-patterns

Anti-patternWhy it failsFix
Unsalted hashing of SSNSSN format is enumerable (~10⁹); attacker rebuilds the mapping table in minutes.Salt + key per tenant; or tokenise via vault.
FPE for an analytics datasetFormat preservation lets a join attack with another dataset recover identity.Use random substitution for analytics datasets that don't need format round-trip.
"GDPR-compliant" pseudonymisation claimGDPR pseudonymised data is still personal data - Article 4(5) is explicit.Either mark output pseudonymised (in scope) or fully anonymise (out of scope).
k = 2 anonymityRe-identification probability is 50 % for the equivalence class.k ≥ 5 typical; k = 10+ for high-risk datasets.
Shuffling a rare-value columnOutliers identify themselves regardless of position.Combine shuffling with generalisation or suppression of outliers.
Number variance ± 1 % on salariesThe variance is smaller than the precision needed to identify; effectively no masking.Variance must exceed the identifying granularity - ± 10 % minimum for salary.
Tokenisation without vault access controlsThe vault becomes the single point of failure.Strict access control + audit logging + separate key custody.
Differential privacy with ε = 100Useless budget; no privacy guarantee.ε ≤ 1 typical for strong privacy; ε ≤ 10 for relaxed cases.

Limitations

  • No single technique fits every field. Pipeline must apply per-field policy (pii-masking-pipeline-builder).
  • Re-identification research evolves. NIST 800-188 Annex documents known attacks; the techniques above are sound under 2024 attack models, not future ones.
  • Utility loss is real. Aggressive anonymisation (high k, low ε) makes the dataset less useful for analytics. Pipeline owner must trade off explicitly.
  • Tooling support varies. Presidio implements the Anonymizer operators above out of the box; k-anonymity / l-diversity / DP typically require additional libraries (ARX, OpenDP, IBM Differential Privacy Library) not part of Presidio.

References

Privacy models - NIST SP 800-188

View source (opens in new window)

Privacy models - NIST SP 800-188

Deep reference for data-masking-techniques-reference SKILL.md. Consult after per-field operators are chosen, when quasi-identifiers remain and the whole dataset's disclosure risk must be bounded.

NIST SP 800-188:2023 ("De-Identifying Government Datasets", csrc.nist.gov/pubs/sp/800/188/final (opens in new window)) formalises statistical privacy models layered above the per-field techniques.

k-anonymity

A dataset is k-anonymous if every record is indistinguishable from at least k - 1 other records when projected on the quasi-identifiers (Sweeney 2002, cited in NIST 800-188).

  • Achieve via: Generalisation (age 47 → "40 - 50"), suppression (drop the row), and aggregation.
  • Picks k: Typical values are k = 5, k = 10, k = 100 depending on dataset size + risk tolerance.
  • Weakness: Vulnerable to homogeneity attack - if all k records share the same sensitive value, k-anonymity doesn't protect it.

l-diversity

Strengthens k-anonymity by requiring at least l well-represented values of the sensitive attribute within each equivalence class (Machanavajjhala et al. 2007).

  • Achieve via: Suppression of records that would break l, or perturbation of sensitive values.
  • Weakness: Vulnerable to skewness / similarity attack - the l values may be semantically similar.

t-closeness

Strengthens l-diversity by requiring the distribution of the sensitive attribute in each equivalence class be close (within t, by Earth Mover's Distance) to the distribution in the overall dataset (Li et al. 2007).

  • Trade-off: Higher t = better utility, lower t = stronger privacy.

Differential privacy

A formal mathematical guarantee: the probability of any output changes by at most a multiplicative factor (e^ε) when a single record is added/removed. ε (epsilon) is the privacy budget - lower ε = stronger privacy.

  • Achieve via: Noise injection (Laplace / Gaussian mechanism) on query outputs, not on the raw dataset.
  • Trade-off: Utility-vs-budget. Apple, Google, US Census 2020 use differential privacy.
  • Cite: NIST SP 800-188:2023 §6; original Dwork 2006 "Calibrating noise to sensitivity."

Picking the model

  • k-anonymity - baseline for quasi-identifier sets; pick k >= 5 (k = 10+ for high-risk datasets).
  • l-diversity - add when a homogeneity attack on the sensitive attribute is plausible.
  • t-closeness - add when the sensitive attribute's distribution itself leaks (skewness / similarity).
  • Differential privacy - use for statistical query release, not raw-dataset export; keep ε <= 1 for strong privacy, ε <= 10 relaxed.

References

  • NIST SP 800-188:2023 "De-Identifying Government Datasets" - csrc.nist.gov/pubs/sp/800/188/final (opens in new window). Definitions of k-anonymity, l-diversity, t-closeness, differential privacy.
  • Sweeney 2002 (k-anonymity), Machanavajjhala et al. 2007 (l-diversity), Li et al. 2007 (t-closeness), Dwork 2006 "Calibrating noise to sensitivity" (differential privacy) - all cited in NIST 800-188.

Related skills

faker-synthetic-data

Substitutes realistic replacement values for PII that a masking or de-identification step removed, nulled, or redacted, so a non-production dataset stays usable. Covers building an injective substitution map that keeps a shared identifier consistent everywhere it appears so joins survive; choosing deterministic (seeded) over random substitution, and the re-identification risk a shared or committed seed reintroduces, since a generator seed is a reproducibility control and not a cryptographic key; preserving field shape where a downstream system validates it, including check-digit values such as payment-card and national-ID numbers plus phone and postal formats; and why a value that merely looks realistic is not yet safe, leaving a residual re-identification measurement over the remaining quasi-identifiers. Use when a masking pipeline has nulled or dropped PII columns and the dataset now needs replacement values that keep cross-table joins intact.

k-anonymity-verifier

Verifies that a masked dataset satisfies k-anonymity, l-diversity, and t-closeness by computing equivalence classes over chosen quasi-identifiers and reporting re-identification risk. Covers quasi-identifier selection heuristics, threshold guidance, pycanon API (k_anonymity / l_diversity / t_closeness / report), ARX Java API and GUI workflow, SmartNoise for differential-privacy comparison, and CI-gate integration. Distinct from data-masking-techniques-reference (which catalogs masking operators but defers k-anonymity measurement to dedicated tooling) and from presidio-pii-detection (which detects PII spans but offers no equivalence-class analysis). Use when you need to confirm whether a masked dataset meets a stated k, l, or t threshold before promoting it to a non-production environment.

pii-categories-reference

Pure-reference catalog of personally identifiable information (PII) categories across GDPR, CCPA/CPRA, NIST SP 800-122, and HIPAA. Defines what counts as personal data under each regime, enumerates the explicit identifiers each regulator lists (GDPR Art. 4(1) and Art. 9 special categories; CPRA sensitive personal information; NIST direct-identifier vs linkable distinction; HIPAA Safe Harbor 18 identifiers), and maps overlapping fields across jurisdictions so a masking pipeline knows which regulator's rules apply. Use as the authoritative source when authoring or reviewing masking rules, classifying a dataset's risk level, or scoping which fields a PII detector must catch.

pii-masking-pipeline-builder

Build-an-X workflow that produces a PII masking pipeline spec from a source-data inventory. Walks the author through (1) classifying each field against pii-categories-reference, (2) picking a masking operator from data-masking-techniques-reference, (3) deciding pseudonymisation (reversible, in GDPR scope) vs anonymisation (irreversible, out of scope), (4) ordering the pipeline (detect → operator → audit), and (5) emitting a deployable config for Presidio + Faker + Synthea wrappers. Output is a YAML pipeline spec plus a per-field rationale table. Use after classifying a dataset's PII risk; this is the workflow that translates classification into runnable masking config.

presidio-pii-detection

Author and run Microsoft Presidio PII detection - wraps presidio-analyzer (PII detector) + presidio-anonymizer (replace/redact/mask/hash/encrypt operators) for scanning datasets, log streams, and free-text fields. Covers AnalyzerEngine + AnonymizerEngine setup, built-in recognizers (PERSON, EMAIL_ADDRESS, CREDIT_CARD, US_SSN, IBAN_CODE, country-specific IDs across US/UK/Spain/Italy/Poland/Singapore/Australia/India and more), custom PatternRecognizer authoring, score thresholds, and CI gating. Use when scanning *existing* data for PII (vs synthesising fresh fixtures with synthetic-pii-generator).

synthea-healthcare-data

Author and run Synthea (MITRE's open-source synthetic patient population simulator) to produce HIPAA-safe synthetic medical records for testing health IT systems. Covers Gradle build, population-size and state-specific generation, FHIR R4 / STU3 / DSTU2 / C-CDA / CSV / CPCDS output formats, disease-module customisation, and the lifecycle-simulation approach (birth-through-death patient journeys with realistic demographics). Use when testing FHIR servers, EHR integrations, claims processing, or any health IT system that needs realistic patient records without HIPAA exposure (distinct from faker-synthetic-data which is generic; this is health-domain-specific).

test-data-governance-reference

Pure-reference catalog of test-data lifecycle governance: retention schedules for test datasets, cross-environment data-sharing agreements, deletion of test data containing real PII, refresh cadence, access controls, and the legal basis for each policy under GDPR Art. 5 storage limitation and NIST SP 800-122. Use when defining a data-steward role for test environments, authoring a retention policy for a test database, scoping a data-sharing agreement before promoting a dataset from production to staging, or determining the deletion timeline for any test fixture that contains live personal data.