| name | anonymize-data |
| description | Strip PII from sample API payloads (names, emails, phones, IDs, IBANs, addresses) before committing sample data. Use before checking fixtures into a repo. |
Build an anonymization pipeline that takes production data exports and replaces PII with realistic fake data while preserving structure and relationships, ready for use in mock and dev environments.
Ask for:
- Which data types to anonymize
- Source format (JSON, CSV, database dump)
- Output format
Fields to anonymize
| Field type | Strategy | Example |
|---|
| Names (first, last) | Replace with locale-appropriate fake names | "Ivan" → "Ana" |
| Emails | Generate from fake name + random domain | "m@real.com" → "ana.novak@example.com" |
| Phone numbers | Preserve format, randomize digits | "+385 91 234 5678" → "+385 91 876 5432" |
| Social security / OIB | Generate valid-format fake IDs | "12345678901" → "98765432109" |
| IBANs | Generate valid-checksum fake IBANs per country | "HR1234..." → "HR9876..." |
| Photos / image URLs | Replace with placeholder avatars or generated images | URL → "https://api.dicebear.com/..." |
| Addresses | Replace with fake addresses in same city/country | Real address → Fake address |
| Dates of birth | Shift by random offset (preserve age range) | 1990-03-15 → 1991-07-22 |
Implementation
Create an Anonymizer package with:
public protocol FieldAnonymizer: Sendable {
func anonymize(_ value: String) -> String
}
public struct NameAnonymizer: FieldAnonymizer { ... }
public struct EmailAnonymizer: FieldAnonymizer { ... }
public struct PhoneAnonymizer: FieldAnonymizer { ... }
public struct IBANAnonymizer: FieldAnonymizer { ... }
public struct SSNAnonymizer: FieldAnonymizer { ... }
public struct PhotoURLAnonymizer: FieldAnonymizer { ... }
Key rules:
- Deterministic: Same input always produces same fake output (use seeded PRNG). This preserves referential integrity across tables.
- Format-preserving: Output matches the field's format/validation rules
- IBAN checksums: Generate valid mod-97 checksums for fake IBANs
- Reversible mapping: Keep a local-only mapping file for debugging (never commit)
CLI tool
Create a command-line target that processes data files:
swift run Anonymizer --input prod-export.json --output mock-data.json --config anonymize.yaml
Config file specifies which JSON paths map to which anonymizer:
rules:
- path: "$.users[*].firstName"
anonymizer: name
- path: "$.users[*].email"
anonymizer: email
- path: "$.users[*].iban"
anonymizer: iban
country: HR
- path: "$.users[*].photoUrl"
anonymizer: photo
Tests
- Every anonymizer has tests confirming output format matches input format
- IBAN anonymizer test verifies mod-97 checksum validity
- Determinism test: same seed + same input = same output
- Referential integrity test: user ID foreign keys still resolve after anonymization
- Round-trip test: anonymize → load into mock server → verify API responses are valid