Mengelola data pribadi secara legal dan etis: mengenali PII, memahami kewajiban GDPR, teknik masking & anonymization (pseudonimisasi, k-anonymity), dan retention policies, plus praktik menerapkan anonymization di pipeline data

Di episode 18 kalian membatasi siapa yang bisa mengakses data. Episode 19 menangani pertanyaan yang lebih rumit: data apa yang boleh disimpan, untuk berapa lama, dan dalam bentuk apa. Regulasi seperti GDPR (Eropa) dan UU Perlindungan Data Pribadi (Indonesia, berlaku penuh sejak 2024) menuntut organisasi bertanggung jawab atas data pribadi yang mereka kelola.
Sebagai data engineer, kalian adalah orang yang membangun kontrol teknis untuk kepatuhan: mengenali PII, menerapkan masking dan anonymization, serta merancang retention policies. Episode ini membekali kalian dengan praktik yang bisa langsung diterapkan di pipeline.
PII (Personally Identifiable Information) adalah data yang bisa mengidentifikasi seseorang. Contohnya:
| Kategori | Contoh |
|---|---|
| Identitas langsung | Nama lengkap, NIK, nomor passport |
| Kontak | Email, nomor telepon, alamat |
| Keuangan | Nomor kartu kredit, rekening bank |
| Lokasi | Alamat rumah, GPS presisi |
| Online | IP address, cookie, device ID |
Perhatikan IP address dan device ID: banyak organisasi lupa bahwa keduanya PII. Aturan umum: jika data bisa menunjuk ke individu (langsung atau dengan kombinasi), ia PII.
GDPR menetapkan beberapa prinsip yang berdampak teknis pada pipeline:
Prinsip 2 dan 3 menuntut kemampuan teknis yang nyata: menghapus data secara andal di seluruh sistem — termasuk di data lake, backup, dan cache. Ini bukan pekerjaan "copy paste delete"; butuh desain sejak awal.
Ada tingkatan perlindungan yang harus dipilih berdasarkan kebutuhan analisis vs kebutuhan privasi:
| Teknik | Apa yang Terjadi | Bisakah Di-reverse? | Contoh |
|---|---|---|---|
| Masking | Menyembunyikan sebagian nilai | Tidak perlu (data asli di tempat lain) | 0813****1234 |
| Tokenization | Mengganti nilai dengan token | Ya, dengan mapping | token tkn_8f3a |
| Pseudonimisasi | Mengganti identitas dengan alias | Ya, dengan kunci (GDPR-friendly) | customer_abc123 |
| Anonymization | Menghapus identitas permanen | Tidak | agregasi tanpa identitas |
Perbedaan penting: pseudonimisasi adalah penggantian yang bisa dipetakan kembali (dengan kunci terpisah) — GDPR menganggapnya data pribadi, tapi bisa diproses lebih bebas. Anonymization bersifat permanen dan keluar dari cakupan GDPR — tapi harus benar-benar tidak bisa di-reverse.
Sekadar menghapus nama belum cukup — kombinasi atribut (umur, kode pos, pekerjaan) bisa tetap mengidentifikasi seseorang. K-anonymity memastikan setiap kombinasi quasic-identifier muncul minimal di k baris, sehingga mustahil menunjuk satu individu:
import polars as pl
# Sebelum: (usia, kode_pos, pekerjaan) unik untuk 1 orang → mudah diidentifikasi
before = pl.DataFrame({
"usia": [29, 34, 41, 38, 29],
"kode_pos": ["10110", "10230", "10110", "50111", "10110"],
"pekerjaan": ["engineer", "engineer", "analyst", "analyst", "engineer"],
})
# Sesudah: generalisasi & suppression → tiap grup minimal 3 baris
after = before.with_columns(
pl.col("usia").map_batches(lambda s: s.cast(pl.Int64).map_elements(
lambda x: f"{(x // 10) * 10}-{(x // 10) * 10 + 9}",
return_dtype=pl.String)),
)
print(after)Output after menggabungkan usia menjadi rentang 20-29/30-39, dan baris kode_pos 50111 di-suppress (dihapus atau digeneralisasi) agar grup berisi minimal 3 baris. Ini adalah tingkat kehati-hatian yang dituntut untuk dataset publik atau analisis lintas domain.
Data tidak boleh disimpan selamanya. Retention policy menetapkan berapa lama tiap data hidup, lalu apa yang terjadi (dihapus, dianonimkan, atau dipindah ke arsip dingin):
-- Hapus baris yang lebih tua dari 24 bulan (storage limitation)
DELETE FROM raw_customer_profiles
WHERE created_at < now() - interval '24 months';
-- Anonimkan profil menengah: 12-24 bulan hanya menyimpan agregat
CREATE OR REPLACE VIEW analytics.customer_anonymized AS
SELECT
age_bucket,
city_region,
COUNT(*) AS customer_count,
AVG(ltv) AS avg_ltv
FROM raw_customer_profiles
GROUP BY age_bucket, city_region;# Bronze menyimpan raw 30 hari, silver 12 bulan, gold sesuai kebutuhan bisnis
rules:
- prefix: bronze/
expiration: 30d
- prefix: silver/
expiration: 365d
- prefix: gold/
expiration: 730dPrinsipnya: tentukan retention sebelum menyimpan, bukan setelah data menumpuk. Data yang tidak pernah dihapus adalah kewajiban hukum yang berjalan.
Rangkai menjadi pipeline yang menerapkan privacy by design:
import polars as pl
import hashlib
def pseudonymize(series: pl.Series, salt: str) -> pl.Series:
"""Ganti nilai PII dengan token deterministik."""
def h(v):
return "tkn_" + hashlib.sha256(f"{salt}{v}".encode()).hexdigest()[:12]
return series.map_elements(h, return_dtype=pl.String)
def mask_phone(series: pl.Series) -> pl.Series:
return series.str.replace(r"(\d{4})\d{4}(\d{4})", r"$1****$2")
df = pl.read_parquet("bronze/customer_profiles/")
clean = df.with_columns(
pseudonymize(pl.col("email"), salt="STATIC_SALT").alias("email_tok"),
mask_phone(pl.col("phone")).alias("phone_masked"),
).drop(["email", "phone"])
clean.write_parquet("silver/customer_profiles_clean/")Perhatikan: salt untuk pseudonimisasi harus disimpan terpisah dari data — di secrets manager (episode 18), bukan di kode yang sama.
Warning
Pseudonimisasi dengan salt yang sama untuk semua dataset = trivial untuk dibalik. Gunakan salt per dataset dan simpan mapping di sistem yang terproteksi. Dan ingat: anonymization yang benar membuat semua jalur identifikasi (termasuk kombinasi atribut) tertutup — bukan sekadar menghapus kolom nama.
Menganggap menghapus nama = anonymized. Kombinasi atribut lain bisa tetap mengidentifikasi. Gunakan k-anonymity untuk data yang sensitif.
Menyimpan PII lebih lama dari kebutuhan. Retention policy ditetapkan sejak desain, dan dijalankan otomatis — bukan tugas manual bulanan.
Masking di aplikasi, bukan di data. Masking di level dashboard hanya menyembunyikan tampilan — data asli tetap mengalir. Terapkan di lapisan data/warehouse.
Salt pseudonimisasi satu untuk semua. Satu dataset diretas = semua token terbuka. Pisahkan kunci per dataset.
Di episode 19 ini kalian telah membangun kompetensi privacy & compliance:
Di episode 20 selanjutnya kita memastikan semua berjalan sehat: monitoring & alerting pipeline — pipeline metrics, SLA, alerting, dan observability data dengan OpenTelemetry, plus praktik monitoring dashboard. Sampai jumpa di episode 20!