Template: Technique-Focused Client Document
This is a ready-to-adapt example, not a universal recommendation. The pre-populated content uses HMAC-SHA256 keyed hashing for telco MSISDN pseudonymization on GCP — a common technique recommendation in Aliz anonymization engagements. Every client's document will differ based on their identifiers, use cases, and infrastructure.
How to use this template:
- Pre-populated content shows a realistic example. Replace the technique, identifiers, GCP services, and recommendation with the client's actual context.
- Placeholders in
[___ description]markers indicate values that must be filled per engagement. - Adapt blocks explain what to change per section — remove them from the final client-facing document.
See Module 03 for technique details, Module 05 for GCP implementation, and Module 13 for engagement context.
HMAC-SHA256 Keyed Hashing for [Identifier Type] Pseudonymization
Replace "HMAC-SHA256 Keyed Hashing" with the technique name. Replace [Identifier Type] with the client's identifier — MSISDN, IBAN, national ID, etc.
What it does
HMAC-SHA256 replaces sensitive identifiers — such as phone numbers (MSISDNs) — with irreversible, fixed-length pseudonyms derived from a secret cryptographic key. The same identifier always produces the same pseudonym when the same key is used, preserving the ability to join records across tables (e.g., linking billing records to network events by subscriber). Without the key, the pseudonyms cannot be reversed — even by an attacker who knows the format of all possible input values.
This addresses a critical gap in [Client Name]'s current approach: plain (unsalted) hashing of [Identifier Type], which is trivially reversible via dictionary attack because the input domain is finite and enumerable.
When to use it
- Replacing unsalted hashing. Any pipeline that currently applies SHA-256, MD5, or SHA-1 to finite-domain identifiers (phone numbers, national IDs, IBANs) without a secret key. This is the single highest-risk, lowest-effort fix in most legacy anonymization systems.
- Cross-table analytics. When pseudonymized records must be joinable across datasets (billing + network + CRM) using a consistent pseudonym, but the original identifier must not be recoverable by analysts.
- Internal analytics zones. Suitable for Zone 1 (pseudonymized) data in a multi-zone architecture, where operational teams need linkable records but not the raw identifiers.
HMAC is not anonymization — it is pseudonymization. The data remains personal data under GDPR, FADP, and other privacy regulations because the key enables re-identification. For use cases requiring true anonymization (external sharing, data monetization), HMAC should be combined with structural anonymization (k-anonymity) or differential privacy in downstream zones.
How it works
HMAC-SHA256 computes HMAC-SHA256(secret_key, identifier) — a standardized keyed-hash construction (RFC 2104) that produces a 256-bit (32-byte) pseudonym. The key is a cryptographic secret managed separately from the data pipeline.
| Property | Plain SHA-256 | HMAC-SHA256 |
|---|---|---|
| Dictionary attack resistant | No — attacker enumerates all inputs | Yes — key required for precomputation |
| Cross-dataset joins | Yes | Yes (same key) |
| Reversible | Effectively yes for finite domains | No (without key) |
| Key management required | No | Yes — Cloud KMS or HSM |
Why plain hashing fails for [Identifier Type]: [Identifier Type] values follow a structured format with a limited domain (e.g., MSISDNs follow E.164 with ~15 digits per national numbering plan). An attacker can hash every valid value and match against the dataset in minutes on commodity hardware — the same attack that reversed the NYC Taxi dataset in 2014.
Replace the plain-hash comparison with whatever the client currently uses. If they use a dictionary-based system rather than hashing, reframe the "How it works" section as a comparison between dictionary lookup and HMAC.
GCP implementation
Sensitive Data Protection (SDP) provides HMAC via the CryptoHashConfig transform in de-identification templates:
- Transform:
CryptoHashConfigwith akms_wrappedcryptographic key. The HMAC secret is generated separately (32 or 64 bytes), then wrapped with a Cloud KMS symmetricENCRYPT_DECRYPTkey (the KEK). The wrapped blob is stored in the SDP de-identification template. - Key management: The KEK lives in Cloud KMS with HSM protection level (or Cloud EKM for external key management in regulated environments). The SDP service agent — not the Dataflow service account — calls KMS to unwrap the HMAC key at transform time. Grant the SDP service agent
cloudkms.cryptoKeyVersions.useToDecrypton the KEK. - Pipeline integration: SDP de-identification API called from Dataflow (Apache Beam), Cloud Run jobs, or batch pipelines.
- Key rotation: Configure KEK rotation explicitly in Cloud KMS (recommended: 90 days). Auto-rotation does not re-wrap existing blobs — an explicit re-wrap is needed before disabling old KEK versions. HMAC key rotation requires generating a new secret, wrapping it, updating the SDP template, and re-processing historical data (produces new pseudonyms, breaking cross-table joins — plan rotation around the data lifecycle).
- Output format:
CryptoHashConfigproduces a Base64-encoded SHA-256 value. Downstream consumers and schema definitions should expect Base64, not hex.
For pipelines not using SDP, HMAC can be implemented as a custom Beam/Spark UDF. Two patterns: (1) call Cloud KMS macSign per record (simplest, but adds per-record latency and API quota consumption), or (2) unwrap a KMS-wrapped HMAC key into worker memory at pipeline startup and compute HMAC locally (higher throughput, requires secure memory handling).
Alternative — CryptoDeterministicConfig (AES-SIV): If future re-identification is required (e.g., for right-to-erasure by record lookup rather than key destruction), use deterministic encryption instead. AES-SIV is reversible with the key, while HMAC is one-way.
Replace the GCP services with the client's actual infrastructure. For on-prem or hybrid: HashiCorp Vault for key management, custom HMAC UDF in Spark. See Module 05 for the full GCP ↔ on-prem mapping.
Tradeoffs
| Dimension | Assessment |
|---|---|
| Privacy strength | Strong against external attackers (dictionary attack eliminated). Weak against key compromise — the key is a single point of failure. HSM-backed storage and separation of duties mitigate this. |
| Analytical utility | High — consistent pseudonyms enable cross-table joins, aggregations, and trend analysis. Original values (e.g., actual phone numbers for customer lookup) are not available. |
| Performance | Negligible overhead — HMAC is a fast cryptographic operation. No vault lookup latency. Suitable for streaming pipelines at high throughput. |
| Operational complexity | Moderate — requires Cloud KMS setup, key rotation policy, and separation of duties between key administrators and data consumers. |
| Regulatory status | Pseudonymization, not anonymization. Data remains in GDPR scope. Provides a "security measure" under Article 32 and supports the legitimate interest balancing test, but does not exempt data from regulation. |
Recommendation
Immediate action: Replace all unsalted hashing of [Identifier Type] with HMAC-SHA256 using an HMAC secret wrapped by a Cloud KMS KEK (HSM protection level). This eliminates the dictionary attack vulnerability — the single highest risk in [Client Name]'s current architecture — with minimal pipeline changes.
Implementation scope:
- Generate a 32- or 64-byte HMAC secret key
- Create a Cloud KMS keyring with a symmetric
ENCRYPT_DECRYPTkey (HSM protection level) as the KEK - Wrap the HMAC secret with the KEK using the Cloud KMS
encryptAPI - Update the
[Pipeline Name]SDP de-identification template to useCryptoHashConfigwith thekms_wrappedblob and the KEK resource name - Configure IAM: grant the SDP service agent
cloudkms.cryptoKeyVersions.useToDecrypton the KEK. Separate key admin role (Security team) from data consumer roles — no single role should hold both - Establish a key rotation policy aligned with
[Client Name]'s data lifecycle. Note: with a shared HMAC key, right-to-erasure requires physical record deletion (the shared key cannot be destroyed without invalidating all pseudonyms). For subject-level crypto-shredding, a per-subject keying architecture is needed — see Module 07 - Re-process historical data in
[Dataset Name]with the new keyed hash to replace existing unsalted pseudonyms
Estimated effort: [X] engineering days for pipeline changes; [Y] days for historical re-processing. Note: SDP CryptoHashConfig produces Base64-encoded output, which differs in length and character set from hex-encoded hashes. Validate downstream consumers — fixed-width columns, regex validation, or schema contracts may need updates before the switch.
Next steps: This addresses the identifier pseudonymization layer. For a complete anonymization architecture — including structural anonymization of quasi-identifiers and differential privacy for external outputs — see the architecture recommendation document.